import React, { useMemo, useState } from “react”;
// Kalkulačka rovné daně 17 % (CZ)
// – Zadáte hrubou mzdu, počet dětí, nepracující manželku a současný čistý příjem.
// – Odpočet na poplatníka 5000 Kč.
// – 1. a 2. dítě 5000 Kč, 3. dítě 6000 Kč, 4. dítě 7000 Kč, 5. dítě 8000 Kč, další max. 8000 Kč.
// – Přepočítáme dvě varianty odpočtů: (A) od základu daně a (B) jako sleva z daně.
// – Ukážeme novou čistou mzdu a rozdíl proti současnému čistému příjmu.
// – Přidán roční přepočet a možnost exportu do PDF.
import { jsPDF } from “jspdf”;
const CZK = (n: number) =>
isFinite(n)
? n.toLocaleString(“cs-CZ”, {
style: “currency”,
currency: “CZK”,
maximumFractionDigits: 0,
})
: “–”;
const num = (v: string) => {
const s = v.replace(/\s/g, “”).replace(“,”, “.”);
const n = parseFloat(s);
return isNaN(n) ? 0 : n;
};
const clampInt = (n: number, min = 0) =>
Number.isFinite(n) ? Math.max(min, Math.trunc(n)) : min;
const taxRate = 0.17; // 17 %
const DED_SPOUSE = 5000;
const DED_TAXPAYER = 5000;
function childDeduction(kidIndex: number) {
if (kidIndex === 1 || kidIndex === 2) return 5000;
if (kidIndex === 3) return 6000;
if (kidIndex === 4) return 7000;
if (kidIndex === 5) return 8000;
return 8000;
}
function computeDeductions(kids: number, spouse: boolean) {
let total = DED_TAXPAYER + (spouse ? DED_SPOUSE : 0);
for (let i = 1; i <= kids; i++) {
total += childDeduction(i);
}
return total;
}
function computeFromBase(gross: number, kids: number, spouse: boolean) {
const deductions = computeDeductions(kids, spouse);
const taxableBase = Math.max(0, gross - deductions);
const tax = taxableBase * taxRate;
const net = gross - tax;
const effRate = gross > 0 ? tax / gross : 0;
return { deductions, taxableBase, tax, net, effRate };
}
function computeFromTaxCredit(gross: number, kids: number, spouse: boolean) {
const preTax = gross * taxRate;
const credits = computeDeductions(kids, spouse);
const tax = Math.max(0, preTax – credits);
const net = gross – tax;
const effRate = gross > 0 ? tax / gross : 0;
return { credits, preTax, tax, net, effRate };
}
export default function FlatTaxCalculator17() {
const [grossInput, setGrossInput] = useState(“40000”);
const [kidsInput, setKidsInput] = useState(“0”);
const [spouse, setSpouse] = useState(false);
const [currentNetInput, setCurrentNetInput] = useState(“0”);
const gross = useMemo(() => Math.max(0, num(grossInput)), [grossInput]);
const kids = useMemo(() => clampInt(num(kidsInput), 0), [kidsInput]);
const currentNet = useMemo(
() => Math.max(0, num(currentNetInput)),
[currentNetInput]
);
const base = useMemo(() => computeFromBase(gross, kids, spouse), [gross, kids, spouse]);
const credit = useMemo(() => computeFromTaxCredit(gross, kids, spouse), [gross, kids, spouse]);
const diffBase = base.net – currentNet;
const diffCredit = credit.net – currentNet;
const exportPDF = () => {
const doc = new jsPDF();
doc.text(“Kalkulačka rovné daně 17 %”, 10, 10);
doc.text(`Hrubá mzda: ${gross} Kč`, 10, 20);
doc.text(`Počet dětí: ${kids}`, 10, 30);
doc.text(`Nepracující manžel/ka: ${spouse ? “Ano” : “Ne”}`, 10, 40);
doc.text(“— Varianta A —“, 10, 60);
doc.text(`Nová čistá mzda: ${base.net} Kč`, 10, 70);
doc.text(“— Varianta B —“, 10, 90);
doc.text(`Nová čistá mzda: ${credit.net} Kč`, 10, 100);
doc.save(“rovna_dan.pdf”);
};
return (
Kalkulačka rovné daně 17 %
Návrhový model. Odpočty: poplatník {DED_TAXPAYER} Kč, manžel/ka {DED_SPOUSE} Kč, děti dle pořadí. Výsledky ukazují dvě možné interpretace.
setGrossInput(e.target.value)}
className=”w-full rounded-xl border px-3 py-2″
placeholder=”40 000″
/>
setKidsInput(e.target.value)}
className=”w-full rounded-xl border px-3 py-2″
placeholder=”0″
/>
setCurrentNetInput(e.target.value)}
className=”w-full rounded-xl border px-3 py-2″
placeholder=”32 500″
/>
Roční přepočet
Měsíční čistá mzda × 12:
Varianta A: {CZK(base.net * 12)}
Varianta B: {CZK(credit.net * 12)}
{title}
{label}
{value}
);
}
function Divider() {
return ;
}