Skip to content

feat: Add eFiling Summary modal with LHDN-exact field mapping#4

Open
vicksk13 wants to merge 20 commits into
mainfrom
development
Open

feat: Add eFiling Summary modal with LHDN-exact field mapping#4
vicksk13 wants to merge 20 commits into
mainfrom
development

Conversation

@vicksk13

Copy link
Copy Markdown
Owner

Adds eFiling Guide modal (Settings → Export eFiling Summary) that mirrors the actual LHDN BE form pages exactly:

  • Page 3 (Pendapatan): Statutory income labels, MTD, aggregate income
  • Page 4 (Pelepasan): All relief fields matching LHDN exact wording
  • Page 5 (Rumusan): Tax computation breakdown showing "Tax on the first / Tax on the balance at rate X%" — matches ef.hasil.gov.my/eBE2026/Rumusan

Includes Download PDF with print-ready layout. EN/BM bilingual.

vicksk13 added 14 commits May 6, 2026 22:22
Adds a brandbook-derived dark theme alongside the existing light theme.

Dark canvas stacked from brandbook --black (#1D1B2D) upward through
--charcoal (#353140) for surface elevation. Text runs from brandbook
--off-white (#FAF7F5) down to --mid-gray (#9A9498) for hierarchy.

Brand red lifted from #B63B2C to #EB6E5E for WCAG AA contrast on dark
backgrounds. Gold nudged to #C9993D for the same reason.

Restores the Light/Dark toggle in Settings > Appearance. Theme
preference persisted to localStorage. No logic, routing, or data
changes — styling only.
Reorders navigation tabs across both mobile and desktop to prioritise
Income as the primary entry point. Relief moves to second, Receipts
third, Settings last. Default landing tab updated from Relief to Income.

More tab renamed to Settings in both English and Bahasa Malaysia
(Tetapan). Internal tab key unchanged — display label only.

No logic, routing, state, or data handling was modified.
Reorders navigation tabs across both mobile and desktop to prioritise
Income as the primary entry point. Relief moves to second, Receipts
third, Settings last. Default landing tab updated from Relief to Income.

More tab renamed to Settings in both English and Bahasa Malaysia
(Tetapan). Internal tab key unchanged — display label only.

No logic, routing, state, or data handling was modified.
… drawer

Adds a two-part user guide system to help new users understand the
MakeCents workflow without support intervention.

Option B (first-launch modal): appears automatically on first login,
tracked via localStorage["makecentstax-guide-seen"] so it shows exactly
once. Covers all 4 steps — income, scan, manage, export. Dismissed via
CTA or clicking outside. Both EN and BM strings included.

Option C (persistent drawer): "How it works" entry in the desktop
sidebar nav and a button in the mobile Income header. Opens a slide-in
panel (right on desktop, bottom sheet on mobile) with the same 4 steps
shown as a numbered flow with connecting lines. Always accessible after
the modal is dismissed.

No logic, data, or routing changes. Styling follows brandbook tokens
throughout — DM Serif Display for headings, DM Sans for body, brand red
accent, off-white backgrounds.
✅ Brandbook colours, DM Sans + DM Serif Display
✅ Light + dark mode with toggle in Settings
✅ Green removed, gold retained
✅ Nav order — Income → Relief → Receipts → Settings
✅ "More" renamed to Settings (EN + BM)
✅ First-launch guide modal + persistent How it works drawer
The How it works button was conditionally rendered only on the Income
tab header on mobile, making it invisible on Receipts and Settings.

Removed the tab === "income" guard so the button now appears in the
header across all non-relief mobile tabs. Relief is unaffected — it
uses its own full-screen header component.

No logic or data changes. Styling unchanged.
✅ DM Sans + DM Serif Display (italic on numerals)
✅ Full brandbook colour tokens — light + dark
✅ Dark mode toggle in Settings
✅ Green removed everywhere, gold kept
✅ Nav order — Income → Relief → Receipts → Settings
✅ "More" → "Settings" (EN + BM)
✅ App opens on Income by default
✅ First-launch guide modal (once only, localStorage flagged)
✅ "How it works" drawer — desktop sidebar + mobile header
✅ Mobile "How it works" shows on all tabs, not just Income
Fixes three issues found during brandbook compliance audit of Dev.jsx:

1. BROKEN TRANSLATION KEY — L('your refund') called with a key that
   didn't exist in TRANS (EN or BM), causing the hero card label to
   display the raw string "your refund" in lowercase. Added:
     EN: your_refund = "YOUR REFUND"
     BM: your_refund = "BAYARAN BALIK ANDA"
   Fixed both call sites (mobile Header + desktop ReliefTab KPI card)
   to use L('your_refund').

2. MOBILE HOW IT WORKS MISSING ON RELIEF TAB — The Relief tab uses the
   full <Header> stats component. Unlike the other 3 tabs, it had no
   "How it works" button, contradicting the "shows on all tabs" spec.
   Added onHowItWorks prop to Header, wired it to setGuideDrawer(true),
   and placed the button in the top-right alongside the YA selector.

3. HARDCODED STALE OFF-WHITE — Desktop sidebar Scan Receipt button used
   color: "#FBF7EE" (old brand value). Corrected to "#FAF7F5" (brandbook
   off-white token) for both text color and icon color.

Font audit — all clear:
  - DM Sans: Google Fonts import ✓, FONT constant ✓, html/body ✓
  - DM Serif Display: 20 usages — 14 italic (all RM numerals) ✓,
    6 upright (display headings, wordmark, empty states) ✓
  - Zero Poppins/Fraunces remaining ✓
#ChangeStatus1your_refund key — EN: "YOUR REFUND", BM: "BAYARAN BALIK ANDA"✅ lines 597, 8392Both L('your refund') broken call sites fixed✅ lines 2863, 32143"How it works" on mobile Relief tab (onHowItWorks prop)✅ lines 2514, 2806, 28244#FBF7EE fully removed✅ zero hits5Replaced with brandbook #FAF7F5✅ lines 2482, 24876DM Sans + DM Serif Display constants✅ lines 412–4137Google Fonts import updated✅ line 48108html/body font-family = DM Sans✅ line 48169Nav order Income → Relief → Receipts → Settings (both layouts)✅ lines 2443–2446, 3129–313210App opens on Income tab✅ line 151211"More" → "Settings" EN + BM✅ lines 453, 69912First-launch guide modal + localStorage flag✅ lines 338, 1622, 291413Dark mode theme object✅ line 38714Dark mode toggle in Settings✅ lines 1487–1491, 2336, 433915No green tokens anywhere✅ zero hits16Gold retained (light + dark)✅ lines 378, 40117FONT_DISPLAY non-italic: only wordmark (22px) + welcome headline (42px)✅ exactly 218Poppins / Fraunces fully gone✅ zero hits
Adds a full-screen eFiling Guide modal accessible from Settings → Data & Export.

The modal maps all user inputs to the corresponding LHDN BE form sections:
- Section B: Employment income (B1a/b/c, D1, E1, E2) per employer
- Section C: Rental income with deductible expenses
- Aggregate income total
- Section F: All relief claims with LHDN codes (C1–C24) and caps applied
- Chargeable income computation
- Tax payable using YA2025 progressive brackets with bracket highlighted
- RM400 individual rebate applied where eligible (chargeable ≤ RM35,000)
- MTD/PCB offset with final balance due or refund card

Download PDF opens a print-ready HTML page in a new tab with auto print trigger.

All labels are bilingual (EN/BM) following the app language selection.
Calculations mirror existing app logic — same groupCapped, itemTotalRaw, BK brackets.

Files changed: src/App.jsx
@vercel

vercel Bot commented May 14, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
ringgit Ready Ready Preview, Comment Jun 3, 2026 3:27pm

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2d19fbcf9d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/App.jsx
const rm = (n) => `RM ${fmt(n)}`;

// ── Totals ───────────────────────────────────────────────
const totalEmpIncome = incomes.reduce((s, i) => s + (i.amount || 0) + (i.bonus || 0) + (i.otherAllowances || 0), 0);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Avoid double-counting bonuses in filing totals

When an employment record has a bonus, this summary overstates income because IncomeTab.handleSave stores amount as the total of gross salary + bonus + other allowances, but this line adds i.bonus on top of i.amount again. That makes the eFiling summary's statutory income, chargeable income, tax computation, and final balance higher than the app's existing tax summary for any taxpayer who entered or scanned a bonus.

Useful? React with 👍 / 👎.

Comment thread src/App.jsx

const incomeRowsHTML = incomes.map((inc, idx) => {
return `
${(incomes.length > 1 || inc.employer) ? `<tr class="sec-hdr"><td colspan="2">${isBM ? "Majikan" : "Employer"}${incomes.length > 1 ? ` ${idx + 1}` : ""}: <strong>${inc.employer || "—"}</strong></td></tr>` : ""}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Escape user fields before writing the print window

If an employer name comes from an imported backup or the EA parser with HTML such as an event handler, clicking Download PDF writes it directly into a same-origin window.open document and executes it instead of displaying text. Please HTML-escape dynamic values before interpolating them into document.write; React's normal escaping does not apply in this generated HTML path.

Useful? React with 👍 / 👎.

vicksk13 added 2 commits June 3, 2026 23:01
…ef-rules

Add YA2026/2027 relief updates: prompts, caps, UI logic and tests
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant