This commit is contained in:
Jordy Hoogeveen
2026-09-15 14:02:17 +02:00
parent 750dc69e56
commit 0b67f346e1
19 changed files with 449 additions and 161 deletions
+19 -19
View File
@@ -3,7 +3,7 @@ import { useApp } from "../context/AppContext.jsx";
import { fmt, pct, fmtDatum } from "../utils/format.js";
import { GREEN, RED, GOLD } from "../constants/index.js";
const TEAL = "#a855f7";
import { VCard, VBadge } from "../components/ui/index.jsx";
export default function DashboardTab() {
@@ -27,9 +27,9 @@ export default function DashboardTab() {
const progressPct = Math.min(totEV / doel, 1);
const milestones = [0, 0.25, 0.5, 0.75, 1].map((f) => f * doel);
const kpis = [
{ label: "Start eigen vermogen", val: fmt(startEV), accent: TEAL},
{ label: "Extra geïnvesteerde fiat", val: fmt(extraFiat), accent: TEAL},
{ label: "Totaal geïnvesteerde fiat", val: fmt(totaalFiat), accent: TEAL},
{ label: "Start eigen vermogen", val: fmt(startEV), accent: T.accentTekst},
{ label: "Extra geïnvesteerde fiat", val: fmt(extraFiat), accent: T.accentTekst},
{ label: "Totaal geïnvesteerde fiat", val: fmt(totaalFiat), accent: T.accentTekst},
{ label: "Totaal eigen vermogen", val: fmt(totEV), accent: GREEN },
{ label: "Winst op investering", val: fmt(winst), accent: winst >= 0 ? GREEN : RED },
{ label: "ROI %", val: totaalFiat > 0 ? pct(roi, 2) : "—", accent: roi >= 0 ? GREEN : RED },
@@ -91,19 +91,19 @@ export default function DashboardTab() {
<div style={{ display: "flex", alignItems: "center", gap: 10 }}>
<span style={{ fontSize: 16 }}>🎯</span>
<span style={{ fontWeight: 600 }}>Doel &amp; Bijbehorende Progressie</span>
<VBadge label={fmt(doel)} color={TEAL} />
<VBadge label={fmt(doel)} color={T.accentTekst} />
</div>
<span style={{ color: T.muted, fontSize: 13 }}>{pct(progressPct)} behaald</span>
</div>
<div style={{
height: 14, background: "rgba(255,255,255,0.07)",
height: 14, background: T.inputBg,
borderRadius: 99, overflow: "hidden",
position: "relative", marginBottom: 8,
}}>
<div style={{
position: "absolute", inset: 0,
width: `${progressPct * 100}%`,
background: "linear-gradient(90deg, #7c3aed, #a855f7)",
background: `linear-gradient(90deg, ${T.accent}, ${T.accentLicht})`,
borderRadius: 99, transition: "width 0.7s ease",
}} />
{[0.25, 0.5, 0.75].map((f) => (
@@ -130,7 +130,7 @@ export default function DashboardTab() {
<div style={{ fontWeight: 600 }}>Ontwikkeling van Eigen Vermogen</div>
{vData.length >= 2 && (
<div style={{ display: "flex", alignItems: "center", gap: 14, fontSize: 11, color: T.muted }}>
<Legenda kleur="linear-gradient(90deg, #0eddd4, #8b5cf6)" label="Eigen vermogen" />
<Legenda kleur={`linear-gradient(90deg, ${T.chartVan}, ${T.chartTot})`} label="Eigen vermogen" />
<Legenda
kleur={`repeating-linear-gradient(90deg, ${GOLD} 0 5px, transparent 5px 9px)`}
label="Geïnvesteerde fiat"
@@ -146,7 +146,7 @@ export default function DashboardTab() {
</div>
</div>
) : (
<MiniLineChart vData={vData} fiatData={fiatData} darkMode={darkMode} />
<MiniLineChart vData={vData} fiatData={fiatData} darkMode={darkMode} T={T} />
)}
</VCard>
@@ -183,7 +183,7 @@ function crPath(xs, ys, t = 0.4) {
}
// ── Mini inline SVG grafiek ────────────────────────────────────────────────────
function MiniLineChart({ vData, fiatData, darkMode }) {
function MiniLineChart({ vData, fiatData, darkMode, T }) {
const [hovered, setHovered] = useState(null);
const W = 700, H = 230, pl = 62, pr = 16, pt = 16, pb = 52;
const vals = vData.map((d) => d.nettoWaarde || 0);
@@ -203,7 +203,7 @@ function MiniLineChart({ vData, fiatData, darkMode }) {
// afronding zou tussen twee stortingen een dip tekenen die er niet is.
const fiatPath = xs.map((x, i) => `${i ? "L" : "M"} ${x},${fYs[i]}`).join(" ");
const gc = darkMode ? "rgba(255,255,255,0.07)" : "rgba(0,0,0,0.06)";
const lc = darkMode ? "#6b7280" : "#94a3b8";
const lc = T.muted;
const handleMouseMove = (e) => {
const rect = e.currentTarget.getBoundingClientRect();
@@ -236,8 +236,8 @@ function MiniLineChart({ vData, fiatData, darkMode }) {
>
<defs>
<linearGradient id="chartLineGrad" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" stopColor="#0eddd4" />
<stop offset="100%" stopColor="#8b5cf6" />
<stop offset="0%" stopColor={T.chartVan} />
<stop offset="100%" stopColor={T.chartTot} />
</linearGradient>
<linearGradient id="chartFadeMask" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stopColor="white" stopOpacity="1" />
@@ -277,16 +277,16 @@ function MiniLineChart({ vData, fiatData, darkMode }) {
{/* Verticale hover-lijn */}
{h !== null && (
<line x1={xs[h]} y1={pt} x2={xs[h]} y2={pt + iH}
stroke="rgba(255,255,255,0.25)" strokeWidth="1" strokeDasharray="4,3" />
stroke={T.muted} strokeOpacity="0.6" strokeWidth="1" strokeDasharray="4,3" />
)}
{/* Hover punten */}
{h !== null && (
<>
<circle cx={xs[h]} cy={fYs[h]} r="4.5"
fill={GOLD} stroke={darkMode ? "#151c2e" : "#fff"} strokeWidth="2.5" />
fill={GOLD} stroke={T.card} strokeWidth="2.5" />
<circle cx={xs[h]} cy={ys[h]} r="5.5"
fill="#0eddd4" stroke={darkMode ? "#151c2e" : "#fff"} strokeWidth="2.5" />
fill={T.chartVan} stroke={T.card} strokeWidth="2.5" />
</>
)}
@@ -294,13 +294,13 @@ function MiniLineChart({ vData, fiatData, darkMode }) {
{h !== null && (
<g>
<rect x={tipX} y={tipY} width={tipW} height={tipH} rx="7"
fill={darkMode ? "#1a2035" : "#fff"}
stroke="rgba(14,221,212,0.35)" strokeWidth="1" />
fill={T.card}
stroke={T.border} strokeWidth="1" />
<text x={tipX + tipW / 2} y={tipY + 16} fill={lc} fontSize="9" textAnchor="middle">
{fmtDatum(vData[h].datum)}
</text>
<text x={tipX + 10} y={tipY + 33} fill={lc} fontSize="9">Vermogen</text>
<text x={tipX + tipW - 10} y={tipY + 33} fill="#0eddd4" fontSize="10"
<text x={tipX + tipW - 10} y={tipY + 33} fill={T.chartVan} fontSize="10"
fontWeight="700" textAnchor="end">
{fmt(vals[h])}
</text>