Changed color and contrast gradients
This commit is contained in:
@@ -4,12 +4,43 @@
|
|||||||
font-family: 'Outfit', system-ui, sans-serif;
|
font-family: 'Outfit', system-ui, sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
:root {
|
||||||
|
/* Base Colors */
|
||||||
|
--intel-darkest: #0A0E27;
|
||||||
|
--intel-dark: #131937;
|
||||||
|
--intel-medium: #1E2749;
|
||||||
|
--intel-accent: #00D9FF;
|
||||||
|
--intel-warning: #FFB800;
|
||||||
|
--intel-danger: #FF3366;
|
||||||
|
--intel-success: #00FF88;
|
||||||
|
--intel-grid: rgba(0, 217, 255, 0.1);
|
||||||
|
|
||||||
|
/* Text Colors with proper contrast */
|
||||||
|
--text-primary: #FFFFFF;
|
||||||
|
--text-secondary: #E4E8F1;
|
||||||
|
--text-tertiary: #B8C5D9;
|
||||||
|
--text-muted: #8A98B0;
|
||||||
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
background-color: #0A0E27;
|
background-color: #0A0E27;
|
||||||
color: #E4E8F1;
|
color: #E4E8F1;
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Utility Classes for Tailwind-style usage */
|
||||||
|
.bg-intel-darkest { background-color: var(--intel-darkest); }
|
||||||
|
.bg-intel-dark { background-color: var(--intel-dark); }
|
||||||
|
.bg-intel-medium { background-color: var(--intel-medium); }
|
||||||
|
.text-intel-accent { color: var(--intel-accent); }
|
||||||
|
.text-intel-warning { color: var(--intel-warning); }
|
||||||
|
.text-intel-danger { color: var(--intel-danger); }
|
||||||
|
.text-intel-success { color: var(--intel-success); }
|
||||||
|
.border-intel-accent { border-color: var(--intel-accent); }
|
||||||
|
.border-intel-warning { border-color: var(--intel-warning); }
|
||||||
|
.border-intel-danger { border-color: var(--intel-danger); }
|
||||||
|
.border-intel-grid { border-color: var(--intel-grid); }
|
||||||
|
|
||||||
/* Grid background effect */
|
/* Grid background effect */
|
||||||
.grid-bg {
|
.grid-bg {
|
||||||
background-image:
|
background-image:
|
||||||
@@ -75,13 +106,17 @@ body {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Card hover effects */
|
/* Card hover effects with depth */
|
||||||
.intel-card {
|
.intel-card {
|
||||||
background: linear-gradient(135deg, #131937 0%, #1E2749 100%);
|
background: linear-gradient(135deg, #131937 0%, #1E2749 100%);
|
||||||
border: 1px solid rgba(0, 217, 255, 0.1);
|
border: 1px solid rgba(0, 217, 255, 0.2);
|
||||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
position: relative;
|
position: relative;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
box-shadow:
|
||||||
|
0 4px 6px rgba(0, 0, 0, 0.3),
|
||||||
|
0 1px 3px rgba(0, 0, 0, 0.2),
|
||||||
|
inset 0 1px 0 rgba(255, 255, 255, 0.05);
|
||||||
}
|
}
|
||||||
|
|
||||||
.intel-card::after {
|
.intel-card::after {
|
||||||
@@ -93,16 +128,20 @@ body {
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
background: linear-gradient(90deg,
|
background: linear-gradient(90deg,
|
||||||
transparent,
|
transparent,
|
||||||
rgba(0, 217, 255, 0.05),
|
rgba(0, 217, 255, 0.08),
|
||||||
transparent
|
transparent
|
||||||
);
|
);
|
||||||
transition: left 0.5s;
|
transition: left 0.5s;
|
||||||
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.intel-card:hover {
|
.intel-card:hover {
|
||||||
border-color: rgba(0, 217, 255, 0.4);
|
border-color: rgba(0, 217, 255, 0.5);
|
||||||
transform: translateY(-2px);
|
transform: translateY(-2px);
|
||||||
box-shadow: 0 8px 24px rgba(0, 217, 255, 0.15);
|
box-shadow:
|
||||||
|
0 12px 28px rgba(0, 217, 255, 0.2),
|
||||||
|
0 6px 12px rgba(0, 0, 0, 0.4),
|
||||||
|
inset 0 1px 0 rgba(255, 255, 255, 0.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
.intel-card:hover::after {
|
.intel-card:hover::after {
|
||||||
@@ -177,7 +216,7 @@ body {
|
|||||||
box-shadow: 0 0 10px #00FF88;
|
box-shadow: 0 0 10px #00FF88;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Button styles */
|
/* Button styles with depth and glow */
|
||||||
.intel-button {
|
.intel-button {
|
||||||
position: relative;
|
position: relative;
|
||||||
font-family: 'JetBrains Mono', monospace;
|
font-family: 'JetBrains Mono', monospace;
|
||||||
@@ -190,6 +229,9 @@ body {
|
|||||||
transition: all 0.3s;
|
transition: all 0.3s;
|
||||||
border: 1px solid;
|
border: 1px solid;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
box-shadow:
|
||||||
|
0 2px 6px rgba(0, 0, 0, 0.3),
|
||||||
|
inset 0 1px 0 rgba(255, 255, 255, 0.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
.intel-button::before {
|
.intel-button::before {
|
||||||
@@ -200,7 +242,7 @@ body {
|
|||||||
width: 0;
|
width: 0;
|
||||||
height: 0;
|
height: 0;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
background: rgba(255, 255, 255, 0.1);
|
background: rgba(255, 255, 255, 0.15);
|
||||||
transform: translate(-50%, -50%);
|
transform: translate(-50%, -50%);
|
||||||
transition: width 0.5s, height 0.5s;
|
transition: width 0.5s, height 0.5s;
|
||||||
}
|
}
|
||||||
@@ -211,69 +253,102 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.intel-button-primary {
|
.intel-button-primary {
|
||||||
background: rgba(0, 217, 255, 0.15);
|
background: linear-gradient(135deg, rgba(0, 217, 255, 0.2) 0%, rgba(0, 217, 255, 0.15) 100%);
|
||||||
border-color: #00D9FF;
|
border-color: #00D9FF;
|
||||||
color: #00D9FF;
|
color: #00D9FF;
|
||||||
|
text-shadow: 0 0 10px rgba(0, 217, 255, 0.3);
|
||||||
}
|
}
|
||||||
|
|
||||||
.intel-button-primary:hover {
|
.intel-button-primary:hover {
|
||||||
background: rgba(0, 217, 255, 0.25);
|
background: linear-gradient(135deg, rgba(0, 217, 255, 0.3) 0%, rgba(0, 217, 255, 0.25) 100%);
|
||||||
box-shadow: 0 0 20px rgba(0, 217, 255, 0.3);
|
box-shadow:
|
||||||
|
0 0 25px rgba(0, 217, 255, 0.4),
|
||||||
|
0 4px 12px rgba(0, 0, 0, 0.4),
|
||||||
|
inset 0 1px 0 rgba(255, 255, 255, 0.15);
|
||||||
|
transform: translateY(-1px);
|
||||||
}
|
}
|
||||||
|
|
||||||
.intel-button-danger {
|
.intel-button-danger {
|
||||||
background: rgba(255, 51, 102, 0.15);
|
background: linear-gradient(135deg, rgba(255, 51, 102, 0.2) 0%, rgba(255, 51, 102, 0.15) 100%);
|
||||||
border-color: #FF3366;
|
border-color: #FF3366;
|
||||||
color: #FF3366;
|
color: #FF3366;
|
||||||
|
text-shadow: 0 0 10px rgba(255, 51, 102, 0.3);
|
||||||
}
|
}
|
||||||
|
|
||||||
.intel-button-danger:hover {
|
.intel-button-danger:hover {
|
||||||
background: rgba(255, 51, 102, 0.25);
|
background: linear-gradient(135deg, rgba(255, 51, 102, 0.3) 0%, rgba(255, 51, 102, 0.25) 100%);
|
||||||
box-shadow: 0 0 20px rgba(255, 51, 102, 0.3);
|
box-shadow:
|
||||||
|
0 0 25px rgba(255, 51, 102, 0.4),
|
||||||
|
0 4px 12px rgba(0, 0, 0, 0.4),
|
||||||
|
inset 0 1px 0 rgba(255, 255, 255, 0.15);
|
||||||
|
transform: translateY(-1px);
|
||||||
}
|
}
|
||||||
|
|
||||||
.intel-button-success {
|
.intel-button-success {
|
||||||
background: rgba(0, 255, 136, 0.15);
|
background: linear-gradient(135deg, rgba(0, 255, 136, 0.2) 0%, rgba(0, 255, 136, 0.15) 100%);
|
||||||
border-color: #00FF88;
|
border-color: #00FF88;
|
||||||
color: #00FF88;
|
color: #00FF88;
|
||||||
|
text-shadow: 0 0 10px rgba(0, 255, 136, 0.3);
|
||||||
}
|
}
|
||||||
|
|
||||||
.intel-button-success:hover {
|
.intel-button-success:hover {
|
||||||
background: rgba(0, 255, 136, 0.25);
|
background: linear-gradient(135deg, rgba(0, 255, 136, 0.3) 0%, rgba(0, 255, 136, 0.25) 100%);
|
||||||
box-shadow: 0 0 20px rgba(0, 255, 136, 0.3);
|
box-shadow:
|
||||||
|
0 0 25px rgba(0, 255, 136, 0.4),
|
||||||
|
0 4px 12px rgba(0, 0, 0, 0.4),
|
||||||
|
inset 0 1px 0 rgba(255, 255, 255, 0.15);
|
||||||
|
transform: translateY(-1px);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Input fields */
|
/* Input fields with better contrast */
|
||||||
.intel-input {
|
.intel-input {
|
||||||
background: rgba(19, 25, 55, 0.5);
|
background: rgba(19, 25, 55, 0.7);
|
||||||
border: 1px solid rgba(0, 217, 255, 0.2);
|
border: 1px solid rgba(0, 217, 255, 0.3);
|
||||||
color: #E4E8F1;
|
color: #FFFFFF;
|
||||||
padding: 0.625rem 1rem;
|
padding: 0.625rem 1rem;
|
||||||
border-radius: 0.375rem;
|
border-radius: 0.375rem;
|
||||||
font-family: 'JetBrains Mono', monospace;
|
font-family: 'JetBrains Mono', monospace;
|
||||||
font-size: 0.875rem;
|
font-size: 0.875rem;
|
||||||
transition: all 0.3s;
|
transition: all 0.3s;
|
||||||
|
box-shadow:
|
||||||
|
inset 0 2px 4px rgba(0, 0, 0, 0.3),
|
||||||
|
0 1px 0 rgba(255, 255, 255, 0.05);
|
||||||
}
|
}
|
||||||
|
|
||||||
.intel-input:focus {
|
.intel-input:focus {
|
||||||
outline: none;
|
outline: none;
|
||||||
border-color: #00D9FF;
|
border-color: #00D9FF;
|
||||||
box-shadow: 0 0 0 2px rgba(0, 217, 255, 0.1);
|
box-shadow:
|
||||||
background: rgba(19, 25, 55, 0.8);
|
0 0 0 2px rgba(0, 217, 255, 0.2),
|
||||||
|
inset 0 2px 4px rgba(0, 0, 0, 0.2),
|
||||||
|
0 4px 12px rgba(0, 217, 255, 0.15);
|
||||||
|
background: rgba(19, 25, 55, 0.9);
|
||||||
}
|
}
|
||||||
|
|
||||||
.intel-input::placeholder {
|
.intel-input::placeholder {
|
||||||
color: rgba(228, 232, 241, 0.3);
|
color: rgba(228, 232, 241, 0.4);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Stat cards */
|
/* Stat cards with depth and glow */
|
||||||
.stat-card {
|
.stat-card {
|
||||||
background: linear-gradient(135deg, rgba(19, 25, 55, 0.8) 0%, rgba(30, 39, 73, 0.6) 100%);
|
background: linear-gradient(135deg, rgba(19, 25, 55, 0.9) 0%, rgba(30, 39, 73, 0.8) 100%);
|
||||||
border: 1px solid rgba(0, 217, 255, 0.15);
|
border: 1px solid rgba(0, 217, 255, 0.25);
|
||||||
border-radius: 0.5rem;
|
border-radius: 0.5rem;
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
position: relative;
|
position: relative;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
box-shadow:
|
||||||
|
0 4px 12px rgba(0, 0, 0, 0.3),
|
||||||
|
inset 0 1px 0 rgba(255, 255, 255, 0.05);
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card:hover {
|
||||||
|
transform: translateY(-2px);
|
||||||
|
box-shadow:
|
||||||
|
0 8px 20px rgba(0, 217, 255, 0.15),
|
||||||
|
0 4px 12px rgba(0, 0, 0, 0.4),
|
||||||
|
inset 0 1px 0 rgba(255, 255, 255, 0.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
.stat-card::before {
|
.stat-card::before {
|
||||||
@@ -284,13 +359,22 @@ body {
|
|||||||
right: 0;
|
right: 0;
|
||||||
height: 2px;
|
height: 2px;
|
||||||
background: linear-gradient(90deg, transparent, #00D9FF, transparent);
|
background: linear-gradient(90deg, transparent, #00D9FF, transparent);
|
||||||
opacity: 0.5;
|
opacity: 0.7;
|
||||||
|
box-shadow: 0 0 8px rgba(0, 217, 255, 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Modal overlay */
|
/* Modal overlay with proper backdrop */
|
||||||
.modal-overlay {
|
.modal-overlay {
|
||||||
background: rgba(10, 14, 39, 0.95);
|
background: rgba(10, 14, 39, 0.97);
|
||||||
backdrop-filter: blur(8px);
|
backdrop-filter: blur(12px);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Modal card enhancements */
|
||||||
|
.intel-card.modal-card {
|
||||||
|
box-shadow:
|
||||||
|
0 20px 60px rgba(0, 0, 0, 0.6),
|
||||||
|
0 10px 30px rgba(0, 217, 255, 0.1),
|
||||||
|
inset 0 1px 0 rgba(255, 255, 255, 0.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Scrollbar styling */
|
/* Scrollbar styling */
|
||||||
@@ -340,13 +424,89 @@ body {
|
|||||||
|
|
||||||
/* Data table styling */
|
/* Data table styling */
|
||||||
.data-row {
|
.data-row {
|
||||||
border-bottom: 1px solid rgba(0, 217, 255, 0.05);
|
border-bottom: 1px solid rgba(0, 217, 255, 0.1);
|
||||||
transition: all 0.2s;
|
transition: all 0.2s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.data-row:hover {
|
.data-row:hover {
|
||||||
background: rgba(0, 217, 255, 0.03);
|
background: rgba(0, 217, 255, 0.06);
|
||||||
border-bottom-color: rgba(0, 217, 255, 0.2);
|
border-bottom-color: rgba(0, 217, 255, 0.3);
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 217, 255, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Vendor entry cards - high contrast and depth */
|
||||||
|
.vendor-card {
|
||||||
|
background: linear-gradient(135deg, rgba(19, 25, 55, 0.9) 0%, rgba(30, 39, 73, 0.8) 100%);
|
||||||
|
border: 1px solid rgba(0, 217, 255, 0.25);
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
padding: 1rem;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
box-shadow:
|
||||||
|
0 2px 8px rgba(0, 0, 0, 0.3),
|
||||||
|
inset 0 1px 0 rgba(255, 255, 255, 0.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
.vendor-card:hover {
|
||||||
|
background: linear-gradient(135deg, rgba(19, 25, 55, 0.95) 0%, rgba(30, 39, 73, 0.9) 100%);
|
||||||
|
border-color: rgba(0, 217, 255, 0.4);
|
||||||
|
box-shadow:
|
||||||
|
0 4px 16px rgba(0, 217, 255, 0.15),
|
||||||
|
0 2px 8px rgba(0, 0, 0, 0.4),
|
||||||
|
inset 0 1px 0 rgba(255, 255, 255, 0.08);
|
||||||
|
transform: translateY(-2px);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Document list items with depth */
|
||||||
|
.document-item {
|
||||||
|
background: linear-gradient(135deg, rgba(10, 14, 39, 0.9) 0%, rgba(19, 25, 55, 0.8) 100%);
|
||||||
|
border: 1px solid rgba(0, 217, 255, 0.15);
|
||||||
|
border-radius: 0.375rem;
|
||||||
|
padding: 0.75rem;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
box-shadow:
|
||||||
|
0 2px 6px rgba(0, 0, 0, 0.3),
|
||||||
|
inset 0 1px 0 rgba(255, 255, 255, 0.03);
|
||||||
|
}
|
||||||
|
|
||||||
|
.document-item:hover {
|
||||||
|
background: linear-gradient(135deg, rgba(10, 14, 39, 0.95) 0%, rgba(30, 39, 73, 0.9) 100%);
|
||||||
|
border-color: rgba(0, 217, 255, 0.3);
|
||||||
|
box-shadow:
|
||||||
|
0 4px 12px rgba(0, 217, 255, 0.12),
|
||||||
|
0 2px 6px rgba(0, 0, 0, 0.4),
|
||||||
|
inset 0 1px 0 rgba(255, 255, 255, 0.06);
|
||||||
|
transform: translateY(-1px);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* JIRA ticket items with proper contrast */
|
||||||
|
.jira-ticket-item {
|
||||||
|
background: linear-gradient(135deg, rgba(19, 25, 55, 0.85) 0%, rgba(30, 39, 73, 0.75) 100%);
|
||||||
|
border: 1px solid rgba(255, 184, 0, 0.2);
|
||||||
|
border-radius: 0.375rem;
|
||||||
|
padding: 0.75rem;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
box-shadow:
|
||||||
|
0 2px 6px rgba(0, 0, 0, 0.25),
|
||||||
|
inset 0 1px 0 rgba(255, 255, 255, 0.04);
|
||||||
|
}
|
||||||
|
|
||||||
|
.jira-ticket-item:hover {
|
||||||
|
background: linear-gradient(135deg, rgba(19, 25, 55, 0.95) 0%, rgba(30, 39, 73, 0.85) 100%);
|
||||||
|
border-color: rgba(255, 184, 0, 0.35);
|
||||||
|
box-shadow:
|
||||||
|
0 4px 12px rgba(255, 184, 0, 0.15),
|
||||||
|
0 2px 6px rgba(0, 0, 0, 0.35),
|
||||||
|
inset 0 1px 0 rgba(255, 255, 255, 0.06);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* CVE Header card with depth */
|
||||||
|
.cve-header {
|
||||||
|
background: linear-gradient(135deg, rgba(19, 25, 55, 0.95) 0%, rgba(30, 39, 73, 0.9) 100%);
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cve-header:hover {
|
||||||
|
background: linear-gradient(135deg, rgba(30, 39, 73, 0.95) 0%, rgba(42, 52, 88, 0.9) 100%);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Loading spinner */
|
/* Loading spinner */
|
||||||
@@ -361,7 +521,7 @@ body {
|
|||||||
to { transform: rotate(360deg); }
|
to { transform: rotate(360deg); }
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Tooltip */
|
/* Tooltip with enhanced styling */
|
||||||
.tooltip {
|
.tooltip {
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
@@ -373,8 +533,8 @@ body {
|
|||||||
left: 50%;
|
left: 50%;
|
||||||
transform: translateX(-50%);
|
transform: translateX(-50%);
|
||||||
padding: 0.5rem 0.75rem;
|
padding: 0.5rem 0.75rem;
|
||||||
background: #1E2749;
|
background: linear-gradient(135deg, #1E2749 0%, #2A3458 100%);
|
||||||
border: 1px solid rgba(0, 217, 255, 0.3);
|
border: 1px solid rgba(0, 217, 255, 0.4);
|
||||||
border-radius: 0.25rem;
|
border-radius: 0.25rem;
|
||||||
font-size: 0.75rem;
|
font-size: 0.75rem;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
@@ -383,8 +543,43 @@ body {
|
|||||||
transition: opacity 0.3s;
|
transition: opacity 0.3s;
|
||||||
margin-bottom: 0.5rem;
|
margin-bottom: 0.5rem;
|
||||||
font-family: 'JetBrains Mono', monospace;
|
font-family: 'JetBrains Mono', monospace;
|
||||||
|
color: #FFFFFF;
|
||||||
|
box-shadow:
|
||||||
|
0 4px 12px rgba(0, 0, 0, 0.4),
|
||||||
|
0 0 20px rgba(0, 217, 255, 0.2);
|
||||||
}
|
}
|
||||||
|
|
||||||
.tooltip:hover::after {
|
.tooltip:hover::after {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Enhanced heading glow */
|
||||||
|
h1.text-intel-accent,
|
||||||
|
h2.text-intel-accent,
|
||||||
|
h3.text-intel-accent {
|
||||||
|
text-shadow:
|
||||||
|
0 0 20px rgba(0, 217, 255, 0.4),
|
||||||
|
0 0 40px rgba(0, 217, 255, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Enhanced border glow for featured cards */
|
||||||
|
.border-intel-accent {
|
||||||
|
box-shadow: 0 0 15px rgba(0, 217, 255, 0.15);
|
||||||
|
}
|
||||||
|
|
||||||
|
.border-intel-warning {
|
||||||
|
box-shadow: 0 0 15px rgba(255, 184, 0, 0.15);
|
||||||
|
}
|
||||||
|
|
||||||
|
.border-intel-danger {
|
||||||
|
box-shadow: 0 0 15px rgba(255, 51, 102, 0.15);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Quick lookup section enhancement */
|
||||||
|
.quick-lookup-card {
|
||||||
|
background: linear-gradient(135deg, rgba(19, 25, 55, 0.95) 0%, rgba(30, 39, 73, 0.9) 100%);
|
||||||
|
box-shadow:
|
||||||
|
0 4px 16px rgba(0, 0, 0, 0.3),
|
||||||
|
inset 0 1px 0 rgba(255, 255, 255, 0.05),
|
||||||
|
0 0 40px rgba(0, 217, 255, 0.1);
|
||||||
|
}
|
||||||
|
|||||||
@@ -680,7 +680,7 @@ export default function App() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="mb-4 p-3 bg-intel-medium border border-intel-accent/30 rounded">
|
<div className="mb-4 p-3 bg-intel-medium border border-intel-accent/30 rounded">
|
||||||
<p className="text-sm text-gray-300">
|
<p className="text-sm text-white">
|
||||||
<strong className="text-intel-accent">Tip:</strong> You can add the same CVE-ID multiple times with different vendors.
|
<strong className="text-intel-accent">Tip:</strong> You can add the same CVE-ID multiple times with different vendors.
|
||||||
Each vendor will have its own documents folder.
|
Each vendor will have its own documents folder.
|
||||||
</p>
|
</p>
|
||||||
@@ -688,7 +688,7 @@ export default function App() {
|
|||||||
|
|
||||||
<form onSubmit={handleAddCVE} className="space-y-4">
|
<form onSubmit={handleAddCVE} className="space-y-4">
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-xs font-medium text-gray-400 mb-2 uppercase tracking-wider">
|
<label className="block text-xs font-medium text-gray-300 mb-2 uppercase tracking-wider">
|
||||||
CVE ID *
|
CVE ID *
|
||||||
</label>
|
</label>
|
||||||
<div className="relative">
|
<div className="relative">
|
||||||
@@ -721,7 +721,7 @@ export default function App() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-xs font-medium text-gray-400 mb-2 uppercase tracking-wider">
|
<label className="block text-xs font-medium text-gray-300 mb-2 uppercase tracking-wider">
|
||||||
Vendor *
|
Vendor *
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
@@ -736,7 +736,7 @@ export default function App() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-xs font-medium text-gray-400 mb-2 uppercase tracking-wider">
|
<label className="block text-xs font-medium text-gray-300 mb-2 uppercase tracking-wider">
|
||||||
Severity *
|
Severity *
|
||||||
</label>
|
</label>
|
||||||
<select
|
<select
|
||||||
@@ -752,7 +752,7 @@ export default function App() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-xs font-medium text-gray-400 mb-2 uppercase tracking-wider">
|
<label className="block text-xs font-medium text-gray-300 mb-2 uppercase tracking-wider">
|
||||||
Description *
|
Description *
|
||||||
</label>
|
</label>
|
||||||
<textarea
|
<textarea
|
||||||
@@ -766,7 +766,7 @@ export default function App() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-xs font-medium text-gray-400 mb-2 uppercase tracking-wider">
|
<label className="block text-xs font-medium text-gray-300 mb-2 uppercase tracking-wider">
|
||||||
Published Date *
|
Published Date *
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
@@ -815,14 +815,14 @@ export default function App() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="mb-4 p-3 bg-intel-medium border border-intel-warning/30 rounded">
|
<div className="mb-4 p-3 bg-intel-medium border border-intel-warning/30 rounded">
|
||||||
<p className="text-sm text-gray-300">
|
<p className="text-sm text-white">
|
||||||
<strong className="text-intel-warning">Note:</strong> Changing CVE ID or Vendor will move associated documents to the new path.
|
<strong className="text-intel-warning">Note:</strong> Changing CVE ID or Vendor will move associated documents to the new path.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<form onSubmit={handleEditCVESubmit} className="space-y-4">
|
<form onSubmit={handleEditCVESubmit} className="space-y-4">
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-xs font-medium text-gray-400 mb-2 uppercase tracking-wider">CVE ID *</label>
|
<label className="block text-xs font-medium text-gray-300 mb-2 uppercase tracking-wider">CVE ID *</label>
|
||||||
<div className="relative">
|
<div className="relative">
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
@@ -850,7 +850,7 @@ export default function App() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-xs font-medium text-gray-400 mb-2 uppercase tracking-wider">Vendor *</label>
|
<label className="block text-xs font-medium text-gray-300 mb-2 uppercase tracking-wider">Vendor *</label>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
required
|
required
|
||||||
@@ -861,7 +861,7 @@ export default function App() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-xs font-medium text-gray-400 mb-2 uppercase tracking-wider">Severity *</label>
|
<label className="block text-xs font-medium text-gray-300 mb-2 uppercase tracking-wider">Severity *</label>
|
||||||
<select
|
<select
|
||||||
value={editForm.severity}
|
value={editForm.severity}
|
||||||
onChange={(e) => setEditForm({...editForm, severity: e.target.value})}
|
onChange={(e) => setEditForm({...editForm, severity: e.target.value})}
|
||||||
@@ -875,7 +875,7 @@ export default function App() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-xs font-medium text-gray-400 mb-2 uppercase tracking-wider">Description *</label>
|
<label className="block text-xs font-medium text-gray-300 mb-2 uppercase tracking-wider">Description *</label>
|
||||||
<textarea
|
<textarea
|
||||||
required
|
required
|
||||||
value={editForm.description}
|
value={editForm.description}
|
||||||
@@ -886,7 +886,7 @@ export default function App() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-xs font-medium text-gray-400 mb-2 uppercase tracking-wider">Published Date *</label>
|
<label className="block text-xs font-medium text-gray-300 mb-2 uppercase tracking-wider">Published Date *</label>
|
||||||
<input
|
<input
|
||||||
type="date"
|
type="date"
|
||||||
required
|
required
|
||||||
@@ -897,7 +897,7 @@ export default function App() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-xs font-medium text-gray-400 mb-2 uppercase tracking-wider">Status *</label>
|
<label className="block text-xs font-medium text-gray-300 mb-2 uppercase tracking-wider">Status *</label>
|
||||||
<select
|
<select
|
||||||
value={editForm.status}
|
value={editForm.status}
|
||||||
onChange={(e) => setEditForm({...editForm, status: e.target.value})}
|
onChange={(e) => setEditForm({...editForm, status: e.target.value})}
|
||||||
@@ -955,7 +955,7 @@ export default function App() {
|
|||||||
{!addTicketContext && (
|
{!addTicketContext && (
|
||||||
<>
|
<>
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-xs font-medium text-gray-400 mb-2 uppercase tracking-wider">CVE ID *</label>
|
<label className="block text-xs font-medium text-gray-300 mb-2 uppercase tracking-wider">CVE ID *</label>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
required
|
required
|
||||||
@@ -966,7 +966,7 @@ export default function App() {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-xs font-medium text-gray-400 mb-2 uppercase tracking-wider">Vendor *</label>
|
<label className="block text-xs font-medium text-gray-300 mb-2 uppercase tracking-wider">Vendor *</label>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
required
|
required
|
||||||
@@ -979,12 +979,12 @@ export default function App() {
|
|||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
{addTicketContext && (
|
{addTicketContext && (
|
||||||
<div className="p-3 bg-intel-medium border border-intel-warning/30 rounded text-sm text-gray-300">
|
<div className="p-3 bg-intel-medium border border-intel-warning/30 rounded text-sm text-white">
|
||||||
Adding ticket for <strong className="text-intel-warning">{addTicketContext.cve_id}</strong> / <strong className="text-intel-warning">{addTicketContext.vendor}</strong>
|
Adding ticket for <strong className="text-intel-warning">{addTicketContext.cve_id}</strong> / <strong className="text-intel-warning">{addTicketContext.vendor}</strong>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-xs font-medium text-gray-400 mb-2 uppercase tracking-wider">Ticket Key *</label>
|
<label className="block text-xs font-medium text-gray-300 mb-2 uppercase tracking-wider">Ticket Key *</label>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
required
|
required
|
||||||
@@ -995,7 +995,7 @@ export default function App() {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-xs font-medium text-gray-400 mb-2 uppercase tracking-wider">JIRA URL</label>
|
<label className="block text-xs font-medium text-gray-300 mb-2 uppercase tracking-wider">JIRA URL</label>
|
||||||
<input
|
<input
|
||||||
type="url"
|
type="url"
|
||||||
placeholder="https://jira.company.com/browse/VULN-1234"
|
placeholder="https://jira.company.com/browse/VULN-1234"
|
||||||
@@ -1005,7 +1005,7 @@ export default function App() {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-xs font-medium text-gray-400 mb-2 uppercase tracking-wider">Summary</label>
|
<label className="block text-xs font-medium text-gray-300 mb-2 uppercase tracking-wider">Summary</label>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="Brief description"
|
placeholder="Brief description"
|
||||||
@@ -1015,7 +1015,7 @@ export default function App() {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-xs font-medium text-gray-400 mb-2 uppercase tracking-wider">Status</label>
|
<label className="block text-xs font-medium text-gray-300 mb-2 uppercase tracking-wider">Status</label>
|
||||||
<select
|
<select
|
||||||
value={ticketForm.status}
|
value={ticketForm.status}
|
||||||
onChange={(e) => setTicketForm({...ticketForm, status: e.target.value})}
|
onChange={(e) => setTicketForm({...ticketForm, status: e.target.value})}
|
||||||
@@ -1051,12 +1051,12 @@ export default function App() {
|
|||||||
<XCircle className="w-6 h-6" />
|
<XCircle className="w-6 h-6" />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div className="p-3 bg-intel-medium rounded text-sm text-gray-300 mb-4 font-mono">
|
<div className="p-3 bg-intel-medium rounded text-sm text-white mb-4 font-mono">
|
||||||
{editingTicket.cve_id} / {editingTicket.vendor}
|
{editingTicket.cve_id} / {editingTicket.vendor}
|
||||||
</div>
|
</div>
|
||||||
<form onSubmit={handleUpdateTicket} className="space-y-4">
|
<form onSubmit={handleUpdateTicket} className="space-y-4">
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-xs font-medium text-gray-400 mb-2 uppercase tracking-wider">Ticket Key *</label>
|
<label className="block text-xs font-medium text-gray-300 mb-2 uppercase tracking-wider">Ticket Key *</label>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
required
|
required
|
||||||
@@ -1066,7 +1066,7 @@ export default function App() {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-xs font-medium text-gray-400 mb-2 uppercase tracking-wider">JIRA URL</label>
|
<label className="block text-xs font-medium text-gray-300 mb-2 uppercase tracking-wider">JIRA URL</label>
|
||||||
<input
|
<input
|
||||||
type="url"
|
type="url"
|
||||||
value={ticketForm.url}
|
value={ticketForm.url}
|
||||||
@@ -1075,7 +1075,7 @@ export default function App() {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-xs font-medium text-gray-400 mb-2 uppercase tracking-wider">Summary</label>
|
<label className="block text-xs font-medium text-gray-300 mb-2 uppercase tracking-wider">Summary</label>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
value={ticketForm.summary}
|
value={ticketForm.summary}
|
||||||
@@ -1084,7 +1084,7 @@ export default function App() {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-xs font-medium text-gray-400 mb-2 uppercase tracking-wider">Status</label>
|
<label className="block text-xs font-medium text-gray-300 mb-2 uppercase tracking-wider">Status</label>
|
||||||
<select
|
<select
|
||||||
value={ticketForm.status}
|
value={ticketForm.status}
|
||||||
onChange={(e) => setTicketForm({...ticketForm, status: e.target.value})}
|
onChange={(e) => setTicketForm({...ticketForm, status: e.target.value})}
|
||||||
@@ -1137,7 +1137,7 @@ export default function App() {
|
|||||||
<XCircle className="w-5 h-5 text-intel-danger mt-0.5" />
|
<XCircle className="w-5 h-5 text-intel-danger mt-0.5" />
|
||||||
<div>
|
<div>
|
||||||
<p className="font-medium text-intel-danger font-mono">Error</p>
|
<p className="font-medium text-intel-danger font-mono">Error</p>
|
||||||
<p className="text-sm text-gray-400">{quickCheckResult.error}</p>
|
<p className="text-sm text-gray-300">{quickCheckResult.error}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
) : quickCheckResult.exists ? (
|
) : quickCheckResult.exists ? (
|
||||||
@@ -1147,12 +1147,12 @@ export default function App() {
|
|||||||
<p className="font-medium text-intel-success font-mono">✓ CVE Addressed ({quickCheckResult.vendors.length} vendor{quickCheckResult.vendors.length > 1 ? 's' : ''})</p>
|
<p className="font-medium text-intel-success font-mono">✓ CVE Addressed ({quickCheckResult.vendors.length} vendor{quickCheckResult.vendors.length > 1 ? 's' : ''})</p>
|
||||||
<div className="mt-3 space-y-3">
|
<div className="mt-3 space-y-3">
|
||||||
{quickCheckResult.vendors.map((vendorInfo, idx) => (
|
{quickCheckResult.vendors.map((vendorInfo, idx) => (
|
||||||
<div key={idx} className="p-3 bg-intel-dark/50 rounded border border-intel-accent/20">
|
<div key={idx} className="p-3 bg-intel-dark/70 rounded border border-intel-accent/30 shadow-lg">
|
||||||
<p className="font-semibold text-gray-200 mb-2 font-sans">{vendorInfo.vendor}</p>
|
<p className="font-semibold text-white mb-2 font-sans">{vendorInfo.vendor}</p>
|
||||||
<div className="grid grid-cols-2 gap-2 text-sm text-gray-400 mb-2 font-mono">
|
<div className="grid grid-cols-2 gap-2 text-sm text-gray-300 mb-2 font-mono">
|
||||||
<p><strong className="text-gray-300">Severity:</strong> {vendorInfo.severity}</p>
|
<p><strong className="text-white">Severity:</strong> {vendorInfo.severity}</p>
|
||||||
<p><strong className="text-gray-300">Status:</strong> {vendorInfo.status}</p>
|
<p><strong className="text-white">Status:</strong> {vendorInfo.status}</p>
|
||||||
<p><strong className="text-gray-300">Documents:</strong> {vendorInfo.total_documents} attached</p>
|
<p><strong className="text-white">Documents:</strong> {vendorInfo.total_documents} attached</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
@@ -1164,7 +1164,7 @@ export default function App() {
|
|||||||
<AlertCircle className="w-5 h-5 text-intel-warning mt-0.5" />
|
<AlertCircle className="w-5 h-5 text-intel-warning mt-0.5" />
|
||||||
<div>
|
<div>
|
||||||
<p className="font-medium text-intel-warning font-mono">Not Found</p>
|
<p className="font-medium text-intel-warning font-mono">Not Found</p>
|
||||||
<p className="text-sm text-gray-400">This CVE has not been addressed yet. No entry exists in the database.</p>
|
<p className="text-sm text-gray-300">This CVE has not been addressed yet. No entry exists in the database.</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
@@ -1192,7 +1192,7 @@ export default function App() {
|
|||||||
</div>
|
</div>
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
{jiraTickets.filter(t => t.status !== 'Closed').map(ticket => (
|
{jiraTickets.filter(t => t.status !== 'Closed').map(ticket => (
|
||||||
<div key={ticket.id} className="data-row flex items-center justify-between p-3 bg-intel-dark/50 rounded border border-intel-grid hover:border-intel-warning/30">
|
<div key={ticket.id} className="jira-ticket-item flex items-center justify-between">
|
||||||
<div className="flex items-center gap-4 flex-1">
|
<div className="flex items-center gap-4 flex-1">
|
||||||
<a
|
<a
|
||||||
href={ticket.url || '#'}
|
href={ticket.url || '#'}
|
||||||
@@ -1202,9 +1202,9 @@ export default function App() {
|
|||||||
>
|
>
|
||||||
{ticket.ticket_key}
|
{ticket.ticket_key}
|
||||||
</a>
|
</a>
|
||||||
<span className="text-sm text-gray-300 font-mono">{ticket.cve_id}</span>
|
<span className="text-sm text-white font-mono">{ticket.cve_id}</span>
|
||||||
<span className="text-sm text-gray-500 font-mono">({ticket.vendor})</span>
|
<span className="text-sm text-gray-300 font-mono">({ticket.vendor})</span>
|
||||||
{ticket.summary && <span className="text-sm text-gray-400 truncate max-w-xs">{ticket.summary}</span>}
|
{ticket.summary && <span className="text-sm text-gray-300 truncate max-w-xs">{ticket.summary}</span>}
|
||||||
<span className={`status-badge ${
|
<span className={`status-badge ${
|
||||||
ticket.status === 'Open' ? 'status-critical' : 'status-high'
|
ticket.status === 'Open' ? 'status-critical' : 'status-high'
|
||||||
}`}>
|
}`}>
|
||||||
@@ -1213,10 +1213,10 @@ export default function App() {
|
|||||||
</div>
|
</div>
|
||||||
{canWrite() && (
|
{canWrite() && (
|
||||||
<div className="flex gap-2">
|
<div className="flex gap-2">
|
||||||
<button onClick={() => handleEditTicket(ticket)} className="text-gray-500 hover:text-intel-warning transition-colors">
|
<button onClick={() => handleEditTicket(ticket)} className="text-gray-400 hover:text-intel-warning transition-colors">
|
||||||
<Edit2 className="w-4 h-4" />
|
<Edit2 className="w-4 h-4" />
|
||||||
</button>
|
</button>
|
||||||
<button onClick={() => handleDeleteTicket(ticket)} className="text-gray-500 hover:text-intel-danger transition-colors">
|
<button onClick={() => handleDeleteTicket(ticket)} className="text-gray-400 hover:text-intel-danger transition-colors">
|
||||||
<Trash2 className="w-4 h-4" />
|
<Trash2 className="w-4 h-4" />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -1231,7 +1231,7 @@ export default function App() {
|
|||||||
<div className="intel-card rounded-lg p-6 mb-6">
|
<div className="intel-card rounded-lg p-6 mb-6">
|
||||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
|
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
|
||||||
<div className="md:col-span-1">
|
<div className="md:col-span-1">
|
||||||
<label className="block text-xs font-medium text-gray-400 mb-2 uppercase tracking-wider">
|
<label className="block text-xs font-medium text-gray-300 mb-2 uppercase tracking-wider">
|
||||||
<Search className="inline w-4 h-4 mr-1" />
|
<Search className="inline w-4 h-4 mr-1" />
|
||||||
Search CVEs
|
Search CVEs
|
||||||
</label>
|
</label>
|
||||||
@@ -1245,7 +1245,7 @@ export default function App() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-xs font-medium text-gray-400 mb-2 uppercase tracking-wider">
|
<label className="block text-xs font-medium text-gray-300 mb-2 uppercase tracking-wider">
|
||||||
<Filter className="inline w-4 h-4 mr-1" />
|
<Filter className="inline w-4 h-4 mr-1" />
|
||||||
Vendor
|
Vendor
|
||||||
</label>
|
</label>
|
||||||
@@ -1261,7 +1261,7 @@ export default function App() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-xs font-medium text-gray-400 mb-2 uppercase tracking-wider">
|
<label className="block text-xs font-medium text-gray-300 mb-2 uppercase tracking-wider">
|
||||||
<AlertCircle className="inline w-4 h-4 mr-1" />
|
<AlertCircle className="inline w-4 h-4 mr-1" />
|
||||||
Severity
|
Severity
|
||||||
</label>
|
</label>
|
||||||
@@ -1331,7 +1331,7 @@ export default function App() {
|
|||||||
<div key={cveId} className="intel-card rounded-lg relative overflow-hidden">
|
<div key={cveId} className="intel-card rounded-lg relative overflow-hidden">
|
||||||
{/* Clickable CVE Header */}
|
{/* Clickable CVE Header */}
|
||||||
<div
|
<div
|
||||||
className="p-6 cursor-pointer hover:bg-intel-medium/30 transition-all duration-200 select-none"
|
className="cve-header p-6 cursor-pointer transition-all duration-200 select-none"
|
||||||
onClick={() => toggleCVEExpand(cveId)}
|
onClick={() => toggleCVEExpand(cveId)}
|
||||||
>
|
>
|
||||||
<div className="flex items-start justify-between">
|
<div className="flex items-start justify-between">
|
||||||
@@ -1346,17 +1346,17 @@ export default function App() {
|
|||||||
{/* Collapsed: truncated description + summary row */}
|
{/* Collapsed: truncated description + summary row */}
|
||||||
{!isCVEExpanded && (
|
{!isCVEExpanded && (
|
||||||
<div className="ml-8">
|
<div className="ml-8">
|
||||||
<p className="text-gray-400 text-sm truncate mb-2">{vendorEntries[0].description}</p>
|
<p className="text-gray-300 text-sm truncate mb-2">{vendorEntries[0].description}</p>
|
||||||
<div className="flex items-center gap-3 flex-wrap">
|
<div className="flex items-center gap-3 flex-wrap">
|
||||||
<span className={`status-badge status-${highestSeverity.toLowerCase()}`}>
|
<span className={`status-badge status-${highestSeverity.toLowerCase()}`}>
|
||||||
{highestSeverity}
|
{highestSeverity}
|
||||||
</span>
|
</span>
|
||||||
<span className="text-xs text-gray-500 font-mono">{vendorEntries.length} vendor{vendorEntries.length > 1 ? 's' : ''}</span>
|
<span className="text-xs text-gray-300 font-mono">{vendorEntries.length} vendor{vendorEntries.length > 1 ? 's' : ''}</span>
|
||||||
<span className="text-xs text-gray-500 flex items-center gap-1 font-mono">
|
<span className="text-xs text-gray-300 flex items-center gap-1 font-mono">
|
||||||
<FileText className="w-3 h-3" />
|
<FileText className="w-3 h-3" />
|
||||||
{totalDocCount} doc{totalDocCount !== 1 ? 's' : ''}
|
{totalDocCount} doc{totalDocCount !== 1 ? 's' : ''}
|
||||||
</span>
|
</span>
|
||||||
<span className="text-xs text-gray-500 font-mono">
|
<span className="text-xs text-gray-300 font-mono">
|
||||||
{overallStatuses.join(', ')}
|
{overallStatuses.join(', ')}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -1366,8 +1366,8 @@ export default function App() {
|
|||||||
{/* Expanded: full description + metadata */}
|
{/* Expanded: full description + metadata */}
|
||||||
{isCVEExpanded && (
|
{isCVEExpanded && (
|
||||||
<div className="ml-8">
|
<div className="ml-8">
|
||||||
<p className="text-gray-300 mb-3">{vendorEntries[0].description}</p>
|
<p className="text-white mb-3">{vendorEntries[0].description}</p>
|
||||||
<div className="flex items-center gap-2 text-sm text-gray-400 font-mono">
|
<div className="flex items-center gap-2 text-sm text-gray-300 font-mono">
|
||||||
<span>Published: {vendorEntries[0].published_date}</span>
|
<span>Published: {vendorEntries[0].published_date}</span>
|
||||||
<span className="text-intel-accent">•</span>
|
<span className="text-intel-accent">•</span>
|
||||||
<span>{vendorEntries.length} affected vendor{vendorEntries.length > 1 ? 's' : ''}</span>
|
<span>{vendorEntries.length} affected vendor{vendorEntries.length > 1 ? 's' : ''}</span>
|
||||||
@@ -1397,17 +1397,17 @@ export default function App() {
|
|||||||
const isDocExpanded = selectedCVE === cve.cve_id && selectedVendorView === cve.vendor;
|
const isDocExpanded = selectedCVE === cve.cve_id && selectedVendorView === cve.vendor;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div key={cve.id} className="border border-intel-accent/20 rounded-lg p-4 bg-intel-dark/50 hover:bg-intel-dark transition-all">
|
<div key={cve.id} className="vendor-card">
|
||||||
<div className="flex justify-between items-start">
|
<div className="flex justify-between items-start">
|
||||||
<div className="flex-1">
|
<div className="flex-1">
|
||||||
<div className="flex items-center gap-3 mb-2">
|
<div className="flex items-center gap-3 mb-2">
|
||||||
<h4 className="text-lg font-semibold text-gray-200 font-sans">{cve.vendor}</h4>
|
<h4 className="text-lg font-semibold text-white font-sans">{cve.vendor}</h4>
|
||||||
<span className={`status-badge status-${cve.severity.toLowerCase()}`}>
|
<span className={`status-badge status-${cve.severity.toLowerCase()}`}>
|
||||||
{cve.severity}
|
{cve.severity}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-4 text-sm text-gray-400 font-mono">
|
<div className="flex items-center gap-4 text-sm text-gray-300 font-mono">
|
||||||
<span>Status: <span className="font-medium text-gray-300">{cve.status}</span></span>
|
<span>Status: <span className="font-medium text-white">{cve.status}</span></span>
|
||||||
<span className="flex items-center gap-1">
|
<span className="flex items-center gap-1">
|
||||||
<FileText className="w-4 h-4" />
|
<FileText className="w-4 h-4" />
|
||||||
{cve.document_count} doc{cve.document_count !== 1 ? 's' : ''}
|
{cve.document_count} doc{cve.document_count !== 1 ? 's' : ''}
|
||||||
@@ -1445,9 +1445,9 @@ export default function App() {
|
|||||||
|
|
||||||
{/* Documents Section */}
|
{/* Documents Section */}
|
||||||
{isDocExpanded && (
|
{isDocExpanded && (
|
||||||
<div className="mt-4 pt-4 border-t border-intel-accent/20">
|
<div className="mt-4 pt-4 border-t border-intel-accent/30">
|
||||||
<h5 className="text-sm font-semibold text-gray-300 mb-3 flex items-center gap-2 font-mono uppercase tracking-wider">
|
<h5 className="text-sm font-semibold text-white mb-3 flex items-center gap-2 font-mono uppercase tracking-wider">
|
||||||
<FileText className="w-4 h-4" />
|
<FileText className="w-4 h-4 text-intel-accent" />
|
||||||
Documents ({documents.length})
|
Documents ({documents.length})
|
||||||
</h5>
|
</h5>
|
||||||
{documents.length > 0 ? (
|
{documents.length > 0 ? (
|
||||||
@@ -1455,7 +1455,7 @@ export default function App() {
|
|||||||
{documents.map(doc => (
|
{documents.map(doc => (
|
||||||
<div
|
<div
|
||||||
key={doc.id}
|
key={doc.id}
|
||||||
className="data-row flex items-center justify-between p-3 bg-intel-darkest/50 rounded hover:bg-intel-medium/30 transition-all border border-intel-grid"
|
className="document-item flex items-center justify-between"
|
||||||
>
|
>
|
||||||
<div className="flex items-center gap-3 flex-1">
|
<div className="flex items-center gap-3 flex-1">
|
||||||
<input
|
<input
|
||||||
@@ -1464,10 +1464,10 @@ export default function App() {
|
|||||||
onChange={() => toggleDocumentSelection(doc.id)}
|
onChange={() => toggleDocumentSelection(doc.id)}
|
||||||
className="w-4 h-4 text-intel-accent rounded focus:ring-2 focus:ring-intel-accent bg-intel-dark border-intel-accent/50"
|
className="w-4 h-4 text-intel-accent rounded focus:ring-2 focus:ring-intel-accent bg-intel-dark border-intel-accent/50"
|
||||||
/>
|
/>
|
||||||
<FileText className="w-5 h-5 text-intel-accent/70" />
|
<FileText className="w-5 h-5 text-intel-accent" />
|
||||||
<div className="flex-1">
|
<div className="flex-1">
|
||||||
<p className="text-sm font-medium text-gray-200 font-mono">{doc.name}</p>
|
<p className="text-sm font-medium text-white font-mono">{doc.name}</p>
|
||||||
<p className="text-xs text-gray-500 capitalize font-mono">
|
<p className="text-xs text-gray-300 capitalize font-mono">
|
||||||
{doc.type} <span className="text-intel-accent">•</span> {doc.file_size}
|
{doc.type} <span className="text-intel-accent">•</span> {doc.file_size}
|
||||||
{doc.notes && <span> <span className="text-intel-accent">•</span> {doc.notes}</span>}
|
{doc.notes && <span> <span className="text-intel-accent">•</span> {doc.notes}</span>}
|
||||||
</p>
|
</p>
|
||||||
@@ -1496,7 +1496,7 @@ export default function App() {
|
|||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<p className="text-sm text-gray-500 italic font-mono">No documents attached</p>
|
<p className="text-sm text-gray-400 italic font-mono">No documents attached</p>
|
||||||
)}
|
)}
|
||||||
{canWrite() && (
|
{canWrite() && (
|
||||||
<button
|
<button
|
||||||
@@ -1515,16 +1515,16 @@ export default function App() {
|
|||||||
{(() => {
|
{(() => {
|
||||||
const vendorTickets = jiraTickets.filter(t => t.cve_id === cve.cve_id && t.vendor === cve.vendor);
|
const vendorTickets = jiraTickets.filter(t => t.cve_id === cve.cve_id && t.vendor === cve.vendor);
|
||||||
return vendorTickets.length > 0 || canWrite() ? (
|
return vendorTickets.length > 0 || canWrite() ? (
|
||||||
<div className="mt-4 pt-4 border-t border-gray-300">
|
<div className="mt-4 pt-4 border-t border-intel-warning/30">
|
||||||
<div className="flex justify-between items-center mb-3">
|
<div className="flex justify-between items-center mb-3">
|
||||||
<h5 className="text-sm font-semibold text-gray-700 flex items-center gap-2">
|
<h5 className="text-sm font-semibold text-white flex items-center gap-2 font-mono uppercase tracking-wider">
|
||||||
<AlertCircle className="w-4 h-4 text-orange-500" />
|
<AlertCircle className="w-4 h-4 text-intel-warning" />
|
||||||
JIRA Tickets ({vendorTickets.length})
|
JIRA Tickets ({vendorTickets.length})
|
||||||
</h5>
|
</h5>
|
||||||
{canWrite() && (
|
{canWrite() && (
|
||||||
<button
|
<button
|
||||||
onClick={() => openAddTicketForCVE(cve.cve_id, cve.vendor)}
|
onClick={() => openAddTicketForCVE(cve.cve_id, cve.vendor)}
|
||||||
className="text-xs px-2 py-1 text-orange-600 hover:bg-orange-50 rounded border border-orange-300 flex items-center gap-1"
|
className="text-xs px-3 py-1 intel-button intel-button-primary flex items-center gap-1"
|
||||||
>
|
>
|
||||||
<Plus className="w-3 h-3" />
|
<Plus className="w-3 h-3" />
|
||||||
Add Ticket
|
Add Ticket
|
||||||
@@ -1534,32 +1534,32 @@ export default function App() {
|
|||||||
{vendorTickets.length > 0 ? (
|
{vendorTickets.length > 0 ? (
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
{vendorTickets.map(ticket => (
|
{vendorTickets.map(ticket => (
|
||||||
<div key={ticket.id} className="flex items-center justify-between p-2 bg-white rounded border border-gray-200">
|
<div key={ticket.id} className="jira-ticket-item flex items-center justify-between">
|
||||||
<div className="flex items-center gap-3">
|
<div className="flex items-center gap-3 flex-1">
|
||||||
<a
|
<a
|
||||||
href={ticket.url || '#'}
|
href={ticket.url || '#'}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
className="font-mono text-sm font-semibold text-[#0476D9] hover:underline"
|
className="font-mono text-sm font-semibold text-intel-accent hover:text-intel-warning transition-colors"
|
||||||
>
|
>
|
||||||
{ticket.ticket_key}
|
{ticket.ticket_key}
|
||||||
</a>
|
</a>
|
||||||
{ticket.summary && <span className="text-sm text-gray-600 truncate max-w-xs">{ticket.summary}</span>}
|
{ticket.summary && <span className="text-sm text-gray-300 truncate max-w-xs">{ticket.summary}</span>}
|
||||||
<span className={`px-2 py-0.5 rounded text-xs font-medium ${
|
<span className={`status-badge ${
|
||||||
ticket.status === 'Open' ? 'bg-red-100 text-red-800' :
|
ticket.status === 'Open' ? 'status-critical' :
|
||||||
ticket.status === 'In Progress' ? 'bg-yellow-100 text-yellow-800' :
|
ticket.status === 'In Progress' ? 'status-high' :
|
||||||
'bg-green-100 text-green-800'
|
'status-low'
|
||||||
}`}>
|
}`}>
|
||||||
{ticket.status}
|
{ticket.status}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
{canWrite() && (
|
{canWrite() && (
|
||||||
<div className="flex gap-1">
|
<div className="flex gap-2">
|
||||||
<button onClick={() => handleEditTicket(ticket)} className="p-1 text-gray-400 hover:text-orange-600">
|
<button onClick={() => handleEditTicket(ticket)} className="p-1 text-gray-400 hover:text-intel-warning transition-colors">
|
||||||
<Edit2 className="w-3 h-3" />
|
<Edit2 className="w-4 h-4" />
|
||||||
</button>
|
</button>
|
||||||
<button onClick={() => handleDeleteTicket(ticket)} className="p-1 text-gray-400 hover:text-red-600">
|
<button onClick={() => handleDeleteTicket(ticket)} className="p-1 text-gray-400 hover:text-intel-danger transition-colors">
|
||||||
<Trash2 className="w-3 h-3" />
|
<Trash2 className="w-4 h-4" />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
@@ -1567,7 +1567,7 @@ export default function App() {
|
|||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<p className="text-sm text-gray-500 italic">No JIRA tickets linked</p>
|
<p className="text-sm text-gray-400 italic font-mono">No JIRA tickets linked</p>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
) : null;
|
) : null;
|
||||||
@@ -1585,10 +1585,10 @@ export default function App() {
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
{Object.keys(filteredGroupedCVEs).length === 0 && !loading && (
|
{Object.keys(filteredGroupedCVEs).length === 0 && !loading && (
|
||||||
<div className="bg-white rounded-lg shadow-md p-12 text-center">
|
<div className="intel-card rounded-lg p-12 text-center">
|
||||||
<AlertCircle className="w-12 h-12 text-gray-400 mx-auto mb-4" />
|
<AlertCircle className="w-12 h-12 text-gray-400 mx-auto mb-4" />
|
||||||
<h3 className="text-lg font-medium text-gray-900 mb-2">No CVEs Found</h3>
|
<h3 className="text-lg font-medium text-white mb-2 font-mono">No CVEs Found</h3>
|
||||||
<p className="text-gray-600">Try adjusting your search criteria or filters</p>
|
<p className="text-gray-300">Try adjusting your search criteria or filters</p>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user