65 lines
3.9 KiB
TypeScript
65 lines
3.9 KiB
TypeScript
import React from 'react';
|
|
import { TrendingUp } from 'lucide-react';
|
|
import { ResponsiveContainer, BarChart, CartesianGrid, XAxis, YAxis, Tooltip as RechartsTooltip, Legend, Bar } from 'recharts';
|
|
|
|
interface CampaignTabProps {
|
|
campaignComparisonData: any[];
|
|
campaignSortOrder: string;
|
|
setCampaignSortOrder: (order: string) => void;
|
|
}
|
|
|
|
export default function CampaignTab({ campaignComparisonData, campaignSortOrder, setCampaignSortOrder }: CampaignTabProps) {
|
|
return (
|
|
<div style={{ display: "grid", gridTemplateColumns: "1fr", gap: "1.5rem", marginBottom: "2rem" }}>
|
|
<div className="card" style={{ height: '600px', display: 'flex', flexDirection: 'column' }}>
|
|
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', flexWrap: 'wrap', gap: '1rem', marginBottom: '1rem' }}>
|
|
<div>
|
|
<h2 className="card-title" style={{ display: 'flex', alignItems: 'center', gap: '0.5rem', marginBottom: '0.5rem' }}>
|
|
<TrendingUp size={16} /> Kampagnen-Vergleich
|
|
</h2>
|
|
<p style={{ color: 'var(--text-muted)', fontSize: '0.85rem' }}>
|
|
<b style={{ color: 'var(--danger)' }}>Roter Balken:</b> Anteil der Nutzer, die kompromittiert wurden.<br />
|
|
<b style={{ color: 'var(--success)' }}>Grüner Balken:</b> Anteil der Nutzer, die es an die IT gemeldet haben.
|
|
</p>
|
|
</div>
|
|
|
|
<select
|
|
value={campaignSortOrder}
|
|
onChange={e => setCampaignSortOrder(e.target.value)}
|
|
style={{ padding: '0.5rem', borderRadius: '4px', border: '1px solid var(--card-border)', backgroundColor: 'var(--card-bg)', color: 'var(--foreground)', fontSize: '0.9rem', outline: 'none', cursor: 'pointer' }}
|
|
>
|
|
<optgroup label="Risiko (Kompromittierungsrate)">
|
|
<option value="komp-desc">Höchste zuerst (Gefährlichste)</option>
|
|
<option value="komp-asc">Niedrigste zuerst (Sicherste)</option>
|
|
</optgroup>
|
|
<optgroup label="Awareness (Melderate)">
|
|
<option value="meld-desc">Höchste zuerst</option>
|
|
<option value="meld-asc">Niedrigste zuerst</option>
|
|
</optgroup>
|
|
<optgroup label="Zeitpunkt (Gesendet)">
|
|
<option value="date-desc">Neueste zuerst</option>
|
|
<option value="date-asc">Älteste zuerst</option>
|
|
</optgroup>
|
|
</select>
|
|
</div>
|
|
|
|
<div style={{ flex: 1, minHeight: 0, overflowY: 'auto', overflowX: 'hidden', paddingRight: '10px' }}>
|
|
<div style={{ height: `${Math.max(400, campaignComparisonData.length * 60)}px`, width: '100%' }}>
|
|
<ResponsiveContainer width="100%" height="100%">
|
|
<BarChart data={campaignComparisonData} layout="vertical" margin={{ top: 10, right: 30, left: 20, bottom: 10 }}>
|
|
<CartesianGrid strokeDasharray="3 3" opacity={0.2} horizontal={true} vertical={false} />
|
|
<XAxis type="number" stroke="var(--text-muted)" tick={{ fontSize: 12 }} unit="%" />
|
|
<YAxis dataKey="name" type="category" stroke="var(--text-muted)" tick={{ fontSize: 12 }} width={180} />
|
|
<RechartsTooltip cursor={{ fill: 'var(--card-border)', opacity: 0.4 }} contentStyle={{ backgroundColor: 'var(--card-bg)', borderColor: 'var(--card-border)', borderRadius: '8px', color: 'var(--foreground)', boxShadow: '0 4px 6px rgba(0,0,0,0.1)' }} />
|
|
<Legend verticalAlign="top" height={36} iconType="circle" wrapperStyle={{ fontSize: '12px' }} />
|
|
<Bar dataKey="Kompromittierungsrate" fill="var(--danger)" name="Kompromittierungsrate (%)" radius={[0, 4, 4, 0]} maxBarSize={20} />
|
|
<Bar dataKey="Melderate" fill="var(--success)" name="Melderate (%)" radius={[0, 4, 4, 0]} maxBarSize={20} />
|
|
</BarChart>
|
|
</ResponsiveContainer>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|