import React, { useState, useMemo } from 'react';
import { PieChart, Pie, Cell, ResponsiveContainer, Tooltip } from 'recharts';
import { Wallet, Receipt, Building2, AlertCircle, Coins, Gift } from 'lucide-react';
const App = () => {
const [monthlySalary, setMonthlySalary] = useState(2500);
const [monthlyTips, setMonthlyTips] = useState(0);
const [monthlyBonus, setMonthlyBonus] = useState(0);
// 2025/26 Tax Year Constants (England/NI/Wales)
const PERSONAL_ALLOWANCE = 12570; // Standard 1257L Tax Code
const BASIC_RATE_LIMIT = 50270;
const HIGHER_RATE_LIMIT = 125140;
const NI_PRIMARY_THRESHOLD_MONTHLY = 1048; // £12,570 / 12
const NI_UPPER_THRESHOLD_MONTHLY = 4189; // £50,270 / 12
const NI_MAIN_RATE = 0.08; // 8%
const NI_UPPER_RATE = 0.02; // 2%
const EMPLOYER_NI_THRESHOLD_MONTHLY = 417; // £5,000 / 12
const EMPLOYER_NI_RATE = 0.15; // 15%
const calculateBreakdown = (salary, tips, bonus) => {
// Total gross for the month
const totalMonthlyGross = salary + tips + bonus;
const annualEquivalent = totalMonthlyGross * 12;
// 1. Income Tax Calculation (1257L Code)
// Most tips and bonuses are subject to PAYE income tax
let taxableIncomeAnnual = Math.max(0, annualEquivalent - PERSONAL_ALLOWANCE);
let annualTax = 0;
if (taxableIncomeAnnual > (HIGHER_RATE_LIMIT - PERSONAL_ALLOWANCE)) {
const higherPart = Math.max(0, annualEquivalent - HIGHER_RATE_LIMIT);
annualTax += higherPart * 0.45;
taxableIncomeAnnual = HIGHER_RATE_LIMIT - PERSONAL_ALLOWANCE;
}
if (taxableIncomeAnnual > (BASIC_RATE_LIMIT - PERSONAL_ALLOWANCE)) {
const higherPart = taxableIncomeAnnual - (BASIC_RATE_LIMIT - PERSONAL_ALLOWANCE);
annualTax += higherPart * 0.40;
taxableIncomeAnnual = BASIC_RATE_LIMIT - PERSONAL_ALLOWANCE;
}
annualTax += taxableIncomeAnnual * 0.20;
const monthlyTax = annualTax / 12;
// 2. National Insurance (Employee)
// Note: Cash tips given directly to employees usually don't have NI deducted
// via payroll, but bonuses and salary do. We'll assume these are via payroll.
let monthlyNI = 0;
if (totalMonthlyGross > NI_PRIMARY_THRESHOLD_MONTHLY) {
const mainBand = Math.min(totalMonthlyGross, NI_UPPER_THRESHOLD_MONTHLY) - NI_PRIMARY_THRESHOLD_MONTHLY;
monthlyNI += mainBand * NI_MAIN_RATE;
if (totalMonthlyGross > NI_UPPER_THRESHOLD_MONTHLY) {
const upperBand = totalMonthlyGross - NI_UPPER_THRESHOLD_MONTHLY;
monthlyNI += upperBand * NI_UPPER_RATE;
}
}
// 3. Employer NI
let monthlyEmployerNI = 0;
if (totalMonthlyGross > EMPLOYER_NI_THRESHOLD_MONTHLY) {
monthlyEmployerNI = (totalMonthlyGross - EMPLOYER_NI_THRESHOLD_MONTHLY) * EMPLOYER_NI_RATE;
}
const takeHome = totalMonthlyGross - monthlyTax - monthlyNI;
return {
monthlyTax: parseFloat(monthlyTax.toFixed(2)),
monthlyNI: parseFloat(monthlyNI.toFixed(2)),
takeHome: parseFloat(takeHome.toFixed(2)),
employerNI: parseFloat(monthlyEmployerNI.toFixed(2)),
totalCost: parseFloat((totalMonthlyGross + monthlyEmployerNI).toFixed(2)),
totalGross: totalMonthlyGross
};
};
const data = useMemo(() =>
calculateBreakdown(monthlySalary, monthlyTips, monthlyBonus),
[monthlySalary, monthlyTips, monthlyBonus]
);
const chartData = [
{ name: 'Take Home', value: data.takeHome, color: '#10b981' },
{ name: 'Income Tax', value: data.monthlyTax, color: '#3b82f6' },
{ name: 'National Insurance', value: data.monthlyNI, color: '#f59e0b' },
];
const formatCurrency = (val) => `£${val.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`;
return (
);
};
export default App;
{/* Header */}
Standard Tax Code (1257L) • No Student Loan
{/* Input Section */}
{/* Main Grid */}
UK Salary Visualiser
2025/26 Tax Year Estimates
{/* Salary Input */}
{/* Tips Input */}
{/* Bonus Input */}
£
setMonthlySalary(Number(e.target.value))}
className="w-full pl-7 pr-3 py-2 bg-slate-50 border border-slate-200 rounded-lg font-semibold focus:ring-2 focus:ring-blue-500 outline-none"
/>
£
setMonthlyTips(Number(e.target.value))}
className="w-full pl-7 pr-3 py-2 bg-slate-50 border border-slate-200 rounded-lg font-semibold focus:ring-2 focus:ring-blue-500 outline-none"
/>
£
setMonthlyBonus(Number(e.target.value))}
className="w-full pl-7 pr-3 py-2 bg-slate-50 border border-slate-200 rounded-lg font-semibold focus:ring-2 focus:ring-blue-500 outline-none"
/>
Total Monthly Gross:
{formatCurrency(data.totalGross)}
*Calculations assume tips/bonuses are paid via payroll (subject to Tax & NI).
{/* Summary Cards */}
{/* Visualization */}
{chartData.map((entry, index) => (
|
))}
formatCurrency(value)} />
{/* Explainers */}
Estimated Monthly Take Home
{formatCurrency(data.takeHome)}
Monthly Deductions
Income Tax (PAYE)
-{formatCurrency(data.monthlyTax)}
National Insurance
-{formatCurrency(data.monthlyNI)}
Total Deductions
-{formatCurrency(data.monthlyTax + data.monthlyNI)}
Employer Total Cost
Total Gross (Pay + Tips + Bonus)
{formatCurrency(data.totalGross)}
Employer NI (15% rate)
{formatCurrency(data.employerNI)}
Total Cost to Company
{formatCurrency(data.totalCost)}
How your pay is divided
{chartData.map(item => (
))}
{item.name}
{((item.value / data.totalGross) * 100).toFixed(1)}%
How Tips are Taxed
If tips are pooled and paid by your employer (tronc), they usually attract Tax and NI. If paid in cash directly, you are responsible for reporting tax.
Bonuses
Bonuses are treated as regular income. If a bonus pushes you into a higher tax bracket for that month, your take-home may be lower than expected.
Tax Code 1257L
This code allows you £1,047.50 per month tax-free. Everything earned above this is subject to 20%, 40%, or 45% tax.
