From e976e0cb4b2f438ac50762873918c4f3fa958355 Mon Sep 17 00:00:00 2001 From: "viet-anh.n" Date: Wed, 8 Jul 2026 07:56:54 +0000 Subject: [PATCH] [TSC-10] Implement calculation engine with arithmetic operations Add calculator.js with a pure calculate(a, b, operation) engine returning {result} or {error}, wired to the existing HTML UI via an IIFE. Update index.html to load the script and CLAUDE.md to document the new module. Co-Authored-By: Claude Sonnet 4.6 --- CLAUDE.md | 10 +++++---- calculator.js | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++ index.html | 1 + 3 files changed, 69 insertions(+), 4 deletions(-) create mode 100644 calculator.js diff --git a/CLAUDE.md b/CLAUDE.md index 15f587d..8349112 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -6,10 +6,11 @@ Greenfield project. Implementation is driven by the Vexa AI-SDLC pipeline (Jira ``` / -├── index.html # Calculator UI (semantic HTML5) -├── styles.css # Responsive CSS layout and styling -├── README.md # Project overview -└── CLAUDE.md # This file +├── index.html # Calculator UI (semantic HTML5) +├── styles.css # Responsive CSS layout and styling +├── calculator.js # Calculation engine + UI wiring (plain JS, no build step) +├── README.md # Project overview +└── CLAUDE.md # This file ``` ## Build Commands @@ -29,6 +30,7 @@ No dev server or REPL is configured yet. Update this section once the implementa - **Domain**: Simple Calculator — arithmetic operations (add, subtract, multiply, divide at minimum). - **Stack**: Plain HTML/CSS/JS — no framework or build step. - `index.html` contains the full UI structure: operand inputs, operation buttons, calculate/clear buttons, result ``, and an error `

`. +- `calculator.js` exposes a `calculate(a, b, operation)` function returning `{ result }` or `{ error }`, and an IIFE that wires the engine to the DOM. ## Code Style diff --git a/calculator.js b/calculator.js new file mode 100644 index 0000000..9b618b5 --- /dev/null +++ b/calculator.js @@ -0,0 +1,62 @@ +function calculate(a, b, operation) { + switch (operation) { + case 'add': return { result: a + b }; + case 'subtract': return { result: a - b }; + case 'multiply': return { result: a * b }; + case 'divide': + if (b === 0) return { error: 'Division by zero is not allowed.' }; + return { result: a / b }; + default: + return { error: 'Unknown operation: ' + operation }; + } +} + +(function () { + var form = document.getElementById('calculator-form'); + var operationBtns = document.querySelectorAll('button[name="operation"]'); + var resultEl = document.getElementById('result'); + var errorEl = document.getElementById('error-message'); + var selectedOperation = null; + + operationBtns.forEach(function (btn) { + btn.addEventListener('click', function () { + operationBtns.forEach(function (b) { b.setAttribute('aria-pressed', 'false'); }); + btn.setAttribute('aria-pressed', 'true'); + selectedOperation = btn.value; + }); + }); + + form.addEventListener('submit', function (e) { + e.preventDefault(); + resultEl.textContent = ''; + errorEl.textContent = ''; + + var a = parseFloat(document.getElementById('operand1').value); + var b = parseFloat(document.getElementById('operand2').value); + + if (isNaN(a) || isNaN(b)) { + errorEl.textContent = 'Please enter valid numbers for both operands.'; + return; + } + + if (!selectedOperation) { + errorEl.textContent = 'Please select an operation.'; + return; + } + + var outcome = calculate(a, b, selectedOperation); + + if (outcome.error) { + errorEl.textContent = outcome.error; + } else { + resultEl.textContent = outcome.result; + } + }); + + form.addEventListener('reset', function () { + resultEl.textContent = ''; + errorEl.textContent = ''; + operationBtns.forEach(function (btn) { btn.setAttribute('aria-pressed', 'false'); }); + selectedOperation = null; + }); +}()); diff --git a/index.html b/index.html index ccb86de..faf00e3 100644 --- a/index.html +++ b/index.html @@ -51,5 +51,6 @@

+