Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion src/app/[lang]/(main)/tax-visualizer/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,19 @@ const PROVINCE_DATA: Record<string, ProvinceData> = {
{ range: "More than $220,000", rate: "13.16%" },
],
},
"british-columbia": {
name: "British Columbia",
bpa: "$12,932",
brackets: [
{ range: "First $49,279", rate: "5.06%" },
{ range: "$49,279 - $98,560", rate: "7.70%" },
{ range: "$98,560 - $113,158", rate: "10.50%" },
{ range: "$113,158 - $137,407", rate: "12.29%" },
{ range: "$137,407 - $186,306", rate: "14.70%" },
{ range: "$186,306 - $259,829", rate: "16.80%" },
{ range: "More than $259,829", rate: "20.50%" },
],
},
};

interface TaxCalculatorFormProps {
Expand Down Expand Up @@ -98,6 +111,7 @@ function TaxCalculatorForm({
>
<option value="ontario">{t`Ontario`}</option>
<option value="alberta">{t`Alberta`}</option>
<option value="british-columbia">{t`British Columbia`}</option>
</select>
<p className="text-sm text-gray-500 mt-1">
{t`More provinces coming soon.`}
Expand Down Expand Up @@ -293,7 +307,11 @@ export default function TaxCalculatorPage() {
and{" "}
<a
href={localizedPath(
province === "alberta" ? "/alberta" : "/ontario",
province === "alberta"
? "/alberta"
: province === "british-columbia"
? "/british-columbia"
: "/ontario",
i18n.locale,
)}
className="underline"
Expand Down
35 changes: 33 additions & 2 deletions src/lib/personalTaxBreakdown.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,15 @@ export interface PersonalTaxBreakdown {
}

// Federal spending categories with percentages (from existing Sankey data)
// Transfer to Ontario: 6.02%, Transfer to Alberta: 2.30%, Other Provinces: 11.18% (reduced from 13.48)
// Transfer to Ontario: 6.02%, Transfer to Alberta: 2.30%, Transfer to BC: 2.80%, Other Provinces: 8.38% (reduced from 11.18)
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to double check this, I think this was just an estimate from an LLM lol

const FEDERAL_SPENDING_CATEGORIES = [
{ name: "Retirement Benefits", percentage: 14.8 },
{ name: "Children, Community and Social Services", percentage: 5.1 },
{ name: "Employment Insurance", percentage: 4.5 },
{ name: "Transfer to Ontario", percentage: 6.02 },
{ name: "Transfer to Alberta", percentage: 2.3 },
{ name: "Transfers to Other Provinces", percentage: 11.18 },
{ name: "Transfer to British Columbia", percentage: 2.8 },
{ name: "Transfers to Other Provinces", percentage: 8.38 },
{ name: "Interest on Debt", percentage: 9.2 },
{ name: "Indigenous Priorities", percentage: 8.3 },
{ name: "Defence", percentage: 6.7 },
Expand Down Expand Up @@ -90,6 +91,32 @@ const ALBERTA_SPENDING_CATEGORIES = [
{ name: "Other", percentage: 8.7 },
];

const BC_SPENDING_CATEGORIES = [
{ name: "Health", percentage: 43.2 },
{ name: "K-12 Education", percentage: 12.7 },
{ name: "Other Appropriations", percentage: 9.7 },
{ name: "Children, Community and Social Services", percentage: 6.7 },
{ name: "Colleges and Universities", percentage: 4.5 },
{ name: "Finance and Debt", percentage: 3.4 },
{ name: "Children and Family Development", percentage: 3.1 },
{ name: "Interest on Debt", percentage: 3.0 },
{ name: "Municipal Affairs and Housing", percentage: 2.3 },
{ name: "Transportation", percentage: 1.9 },
{ name: "Forestry and Parks", percentage: 1.8 },
{ name: "Public Safety", percentage: 1.5 },
{ name: "Attorney and Solicitor General", percentage: 1.1 },
{ name: "Citizens' Services", percentage: 1.0 },
{ name: "Energy", percentage: 0.7 },
{ name: "Emergency Management", percentage: 0.6 },
{ name: "Water and Resource Stewardship", percentage: 0.4 },
{ name: "Fisheries and Agriculture", percentage: 0.4 },
{ name: "Indigenous Priorities", percentage: 0.4 },
{ name: "Environment", percentage: 0.3 },
{ name: "Tourism, Culture, and Sport", percentage: 0.3 },
{ name: "Economic Development and Trade", percentage: 0.3 },
{ name: "Other", percentage: 5.8 },
];

// Consolidated province configuration
const PROVINCE_DATA: Record<
string,
Expand All @@ -106,6 +133,10 @@ const PROVINCE_DATA: Record<
federalTransferName: "Transfer to Alberta",
spendingCategories: ALBERTA_SPENDING_CATEGORIES,
},
"british-columbia": {
federalTransferName: "Transfer to British Columbia",
spendingCategories: BC_SPENDING_CATEGORIES,
},
};

function formatCurrency(amount: number): string {
Expand Down
30 changes: 30 additions & 0 deletions src/lib/taxCalculator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ export const ONTARIO_BASIC_PERSONAL_AMOUNT = 12399;
// 2024 Alberta basic personal amount
export const ALBERTA_BASIC_PERSONAL_AMOUNT = 21885;

// 2025 British Columbia basic personal amount
export const BC_BASIC_PERSONAL_AMOUNT = 12932;

// 2025 Federal tax brackets
export const FEDERAL_TAX_BRACKETS: TaxBracket[] = [
{ min: 0, max: 57375, rate: 0.145 },
Expand Down Expand Up @@ -49,6 +52,17 @@ export const ALBERTA_TAX_BRACKETS: TaxBracket[] = [
{ min: 355845, max: null, rate: 0.15 },
];

// 2025 British Columbia provincial tax brackets
export const BC_TAX_BRACKETS: TaxBracket[] = [
{ min: 0, max: 49279, rate: 0.0506 },
{ min: 49279, max: 98560, rate: 0.077 },
{ min: 98560, max: 113158, rate: 0.105 },
{ min: 113158, max: 137407, rate: 0.1229 },
{ min: 137407, max: 186306, rate: 0.147 },
{ min: 186306, max: 259829, rate: 0.168 },
{ min: 259829, max: null, rate: 0.205 },
];

export function calculateTaxFromBrackets(
income: number,
brackets: TaxBracket[],
Expand Down Expand Up @@ -145,6 +159,17 @@ export function calculateAlbertaTax(income: number): number {
return Math.max(0, taxOnFullIncome - bpaCredit);
}

export function calculateBCTax(income: number): number {
// Step 1: Calculate tax on full income using progressive brackets
const taxOnFullIncome = calculateTaxFromBrackets(income, BC_TAX_BRACKETS);

// Step 2: Apply BPA as a credit (5.06% of BPA - lowest provincial rate)
const bpaCredit = BC_BASIC_PERSONAL_AMOUNT * 0.0506;

// Step 3: Subtract the credit from the calculated tax
return Math.max(0, taxOnFullIncome - bpaCredit);
}

export function calculateTotalTax(
income: number,
province: string = "ontario",
Expand All @@ -161,6 +186,11 @@ export function calculateTotalTax(
case "alberta":
provincialTax = calculateAlbertaTax(income);
break;
case "british-columbia":
case "british columbia":
case "bc":
provincialTax = calculateBCTax(income);
break;
default:
provincialTax = calculateOntarioTax(income); // Default to Ontario for now
provincialTax += calculateOntarioHealthPm(income);
Expand Down