From 9470a4ec6d62e13f5544c70300b6b7ce4c0268bd Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 15 Jul 2025 14:20:23 +0000 Subject: [PATCH 1/3] Initial plan From a5c2fd6549779fd76879c096ef1812e5e49deb1f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 15 Jul 2025 14:32:22 +0000 Subject: [PATCH 2/3] Modernize calculator UI with theme switching functionality Co-authored-by: haslam93 <36418598+haslam93@users.noreply.github.com> --- .eslintrc.js | 2 +- api/controller.js | 4 +- public/client.js | 37 ++++++ public/default.css | 296 +++++++++++++++++++++++++++++++++++---------- public/index.html | 5 +- 5 files changed, 275 insertions(+), 69 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 9e80f9a..8015305 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -3,7 +3,7 @@ module.exports = { "browser": true, "es2021": true, "mocha": true, - "request": true + "node": true }, "extends": "eslint:recommended", "overrides": [ diff --git a/api/controller.js b/api/controller.js index 949731c..797d0f7 100644 --- a/api/controller.js +++ b/api/controller.js @@ -29,13 +29,13 @@ exports.calculate = function(req, res) { } if (!req.query.operand1 || - !req.query.operand1.match(/^(-)?[0-9\.]+(e(-)?[0-9]+)?$/) || + !req.query.operand1.match(/^(-)?[0-9.]+(e(-)?[0-9]+)?$/) || req.query.operand1.replace(/[-0-9e]/g, '').length > 1) { throw new Error("Invalid operand1: " + req.query.operand1); } if (!req.query.operand2 || - !req.query.operand2.match(/^(-)?[0-9\.]+(e(-)?[0-9]+)?$/) || + !req.query.operand2.match(/^(-)?[0-9.]+(e(-)?[0-9]+)?$/) || req.query.operand2.replace(/[-0-9e]/g, '').length > 1) { throw new Error("Invalid operand2: " + req.query.operand2); } diff --git a/public/client.js b/public/client.js index 1c60f86..25a148d 100644 --- a/public/client.js +++ b/public/client.js @@ -16,6 +16,38 @@ var operand1 = 0; var operand2 = 0; var operation = null; +// Theme management +const themes = ['default', 'dark', 'light', 'colorful']; +let currentThemeIndex = 0; + +function initializeTheme() { + const savedTheme = localStorage.getItem('calculatorTheme'); + if (savedTheme && themes.includes(savedTheme)) { + currentThemeIndex = themes.indexOf(savedTheme); + applyTheme(savedTheme); + } else { + applyTheme(themes[0]); + } + + // Add theme toggle event listener + document.getElementById('themeToggle').addEventListener('click', toggleTheme); +} + +function toggleTheme() { + currentThemeIndex = (currentThemeIndex + 1) % themes.length; + const newTheme = themes[currentThemeIndex]; + applyTheme(newTheme); + localStorage.setItem('calculatorTheme', newTheme); +} + +function applyTheme(theme) { + if (theme === 'default') { + document.documentElement.removeAttribute('data-theme'); + } else { + document.documentElement.setAttribute('data-theme', theme); + } +} + function calculate(operand1, operand2, operation) { var uri = location.origin + "/arithmetic"; @@ -198,3 +230,8 @@ function setLoading(loading) { buttons[i].disabled = loading; } } + +// Initialize theme when DOM is loaded +document.addEventListener('DOMContentLoaded', function() { + initializeTheme(); +}); diff --git a/public/default.css b/public/default.css index c652a2b..6bb9bff 100644 --- a/public/default.css +++ b/public/default.css @@ -1,9 +1,82 @@ +/* Root Variables for Theming */ +:root { + --bg-primary: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + --bg-secondary: rgba(255, 255, 255, 0.95); + --bg-container: rgba(255, 255, 255, 0.1); + --bg-display: rgba(0, 0, 0, 0.7); + --bg-button: rgba(255, 255, 255, 0.2); + --bg-button-hover: rgba(255, 255, 255, 0.3); + --bg-button-operator: rgba(255, 255, 255, 0.3); + --bg-button-operator-hover: rgba(255, 255, 255, 0.5); + --text-primary: #ffffff; + --text-secondary: #ffffff; + --text-display: #ffffff; + --border-color: rgba(255, 255, 255, 0.2); + --shadow-color: rgba(0, 0, 0, 0.3); +} + +/* Dark Theme */ +[data-theme="dark"] { + --bg-primary: linear-gradient(135deg, #2c3e50 0%, #34495e 100%); + --bg-secondary: rgba(52, 73, 94, 0.9); + --bg-container: rgba(0, 0, 0, 0.3); + --bg-display: rgba(0, 0, 0, 0.8); + --bg-button: rgba(52, 73, 94, 0.8); + --bg-button-hover: rgba(52, 73, 94, 1); + --bg-button-operator: rgba(74, 144, 226, 0.8); + --bg-button-operator-hover: rgba(74, 144, 226, 1); + --text-primary: #ecf0f1; + --text-secondary: #bdc3c7; + --text-display: #ecf0f1; + --border-color: rgba(52, 73, 94, 0.5); + --shadow-color: rgba(0, 0, 0, 0.5); +} + +/* Light Theme */ +[data-theme="light"] { + --bg-primary: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%); + --bg-secondary: rgba(255, 255, 255, 0.95); + --bg-container: rgba(255, 255, 255, 0.8); + --bg-display: rgba(52, 73, 94, 0.9); + --bg-button: rgba(255, 255, 255, 0.9); + --bg-button-hover: rgba(255, 255, 255, 1); + --bg-button-operator: rgba(74, 144, 226, 0.9); + --bg-button-operator-hover: rgba(74, 144, 226, 1); + --text-primary: #2c3e50; + --text-secondary: #34495e; + --text-display: #ffffff; + --border-color: rgba(52, 73, 94, 0.2); + --shadow-color: rgba(0, 0, 0, 0.1); +} + +/* Colorful Theme */ +[data-theme="colorful"] { + --bg-primary: linear-gradient(135deg, #ff9a56 0%, #ff6b95 100%); + --bg-secondary: rgba(255, 255, 255, 0.95); + --bg-container: rgba(255, 255, 255, 0.2); + --bg-display: rgba(0, 0, 0, 0.8); + --bg-button: rgba(255, 255, 255, 0.3); + --bg-button-hover: rgba(255, 255, 255, 0.5); + --bg-button-operator: rgba(255, 107, 149, 0.8); + --bg-button-operator-hover: rgba(255, 107, 149, 1); + --text-primary: #ffffff; + --text-secondary: #ffffff; + --text-display: #ffffff; + --border-color: rgba(255, 255, 255, 0.3); + --shadow-color: rgba(255, 107, 149, 0.3); +} + BODY { - height: 100%; - width: 100%; + height: 100vh; + width: 100vw; padding: 0; margin: 0; - background-color: #1b4076; + background: var(--bg-primary); + font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; + display: flex; + align-items: center; + justify-content: center; + overflow: hidden; } @media screen and (min-device-width: 500px) and (min-device-height: 1024px) { @@ -23,69 +96,141 @@ BODY { } .container { - min-width: 250px; - min-height: 531px; - width: 250px; + width: 350px; + background: var(--bg-container); + border-radius: 20px; padding: 25px; - margin: 0 auto; - position: relative; - background-image: url(background.png); - background-size: 300px 531px; - background-repeat: no-repeat; - background-position: center top; + backdrop-filter: blur(10px); + border: 1px solid var(--border-color); + box-shadow: 0 20px 40px var(--shadow-color); + transition: all 0.3s ease; } -#results { - position: relative; - top: 0; - left: 0; +.header { + display: flex; + justify-content: flex-end; + margin-bottom: 10px; +} + +.theme-toggle { + background: var(--bg-button); + border: 1px solid var(--border-color); + border-radius: 50%; + width: 40px; + height: 40px; + font-size: 20px; + cursor: pointer; + transition: all 0.3s ease; + backdrop-filter: blur(10px); + color: var(--text-primary); +} + +.theme-toggle:hover { + background: var(--bg-button-hover); + transform: scale(1.1); + box-shadow: 0 5px 15px var(--shadow-color); } -#buttons { - position: relative; +#results { + margin-bottom: 20px; } #result { - background-color: #9b9b9b; - width: 226px; - height: 63px; + background: var(--bg-display); + width: 100%; + height: 80px; margin: 0; - padding: 0 12px; - position: absolute; - border: 0; - left: 0; - top: 32px; - font-family: system-ui; - font-size: 25px; + padding: 20px; + border: none; + border-radius: 15px; + font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; + font-size: 32px; + font-weight: 300; text-align: right; + color: var(--text-display); + display: flex; + align-items: center; + justify-content: flex-end; + box-shadow: inset 0 5px 10px rgba(0, 0, 0, 0.2); + transition: all 0.3s ease; + box-sizing: border-box; +} + +.box { + width: 100%; +} + +.calculator { + width: 100%; } -/*BUTTON { - background-color: #d5d5d5; +.calculator-buttons { + display: grid; + grid-template-columns: repeat(4, 1fr); + gap: 15px; border: 0; - border-radius: 0; - width: 55px; - height: 42px; - position: absolute; +} + +.span-2 { + grid-column: span 2; +} - font-size: 22px; -}*/ +.btn { + font-size: 18px; + font-weight: 500; + height: 60px; + border: 1px solid var(--border-color); + background: var(--bg-button); + color: var(--text-primary); + border-radius: 15px; + cursor: pointer; + transition: all 0.3s ease; + backdrop-filter: blur(10px); + box-shadow: 0 5px 10px rgba(0, 0, 0, 0.1); + display: flex; + align-items: center; + justify-content: center; +} + +.btn:hover { + background: var(--bg-button-hover); + transform: translateY(-2px); + box-shadow: 0 8px 20px var(--shadow-color); +} + +.btn:active { + transform: translateY(0px); + box-shadow: 0 3px 10px var(--shadow-color); +} -#sign, -#clear { - font-size: 17px; +/* Operator buttons */ +.btn:nth-child(4n) { + background: var(--bg-button-operator); + font-weight: 600; } -#clearEntry { - font-size: 15px; +.btn:nth-child(4n):hover { + background: var(--bg-button-operator-hover); } -#image-icon { - left: 0px; - top: 202px; - position: relative; - width: 55px; - height: 42px; +/* Special styling for specific buttons */ +.btn:nth-child(2), .btn:nth-child(3) { + background: var(--bg-button-operator); + font-size: 16px; +} + +.btn:nth-child(2):hover, .btn:nth-child(3):hover { + background: var(--bg-button-operator-hover); +} + +.btn:last-child { + background: var(--bg-button-operator); + font-weight: 700; + font-size: 20px; +} + +.btn:last-child:hover { + background: var(--bg-button-operator-hover); } .resultchar { @@ -156,31 +301,52 @@ BODY { width: 25px; } -.box { - box-sizing: border-box; - top: 220px; - width: 250px; +/* Loading indicator */ +#loading { position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + background: var(--bg-container); + padding: 15px 30px; + border-radius: 10px; + color: var(--text-primary); + font-weight: 500; + border: 1px solid var(--border-color); + backdrop-filter: blur(10px); } -.span-2 { - grid-column: span 2; +#loading::after { + content: 'Calculating...'; } -.calculator-buttons { - display: grid; - grid-template-columns: repeat(4, 1fr); - border: 0; +/* Responsive Design */ +@media screen and (max-width: 400px) { + .container { + width: 90vw; + padding: 20px; + } + + .btn { + height: 50px; + font-size: 16px; + } + + #result { + font-size: 24px; + height: 60px; + padding: 15px; + } } -.calculator { - max-width: 320px; +@media screen and (min-device-width: 500px) and (min-device-height: 1024px) { + .container { + transform: scale(1.2); + } } -.btn { - font-size: 1em; - height: 45px; - border: 1px solid black; - background-color: #d5d5d5; - margin: 4px; +@media screen and (min-device-width: 1024px) and (min-device-height: 1366px) { + .container { + transform: scale(1.4); + } } diff --git a/public/index.html b/public/index.html index 400c454..fc62fa4 100644 --- a/public/index.html +++ b/public/index.html @@ -5,8 +5,11 @@ -
+