Spaces:
Build error
Build error
| import { useState, useEffect } from 'react'; | |
| export default function Calculator() { | |
| const [current, setCurrent] = useState('0'); | |
| const [previous, setPrevious] = useState(null); | |
| const [operation, setOperation] = useState(null); | |
| const [overwrite, setOverwrite] = useState(false); | |
| // Handle number input | |
| const appendNumber = (number) => { | |
| if (overwrite) { | |
| setCurrent(number.toString()); | |
| setOverwrite(false); | |
| } else { | |
| if (number === '0' && current === '0') return; | |
| if (current === '0' && number !== '.') { | |
| setCurrent(number.toString()); | |
| } else { | |
| setCurrent(current + number); | |
| } | |
| } | |
| }; | |
| // Handle decimal point | |
| const appendDecimal = () => { | |
| if (overwrite) { | |
| setCurrent('0.'); | |
| setOverwrite(false); | |
| return; | |
| } | |
| if (current.includes('.')) return; | |
| setCurrent(current + '.'); | |
| }; | |
| // Clear all | |
| const clear = () => { | |
| setCurrent('0'); | |
| setPrevious(null); | |
| setOperation(null); | |
| setOverwrite(false); | |
| }; | |
| // Delete last digit | |
| const deleteLast = () => { | |
| if (overwrite) { | |
| setCurrent('0'); | |
| setOverwrite(false); | |
| return; | |
| } | |
| if (current.length === 1) { | |
| setCurrent('0'); | |
| return; | |
| } | |
| setCurrent(current.slice(0, -1)); | |
| }; | |
| // Choose operation | |
| const chooseOperation = (op) => { | |
| if (current === '') return; | |
| if (previous !== null) { | |
| compute(); | |
| } | |
| setOperation(op); | |
| setPrevious(current); | |
| setCurrent(''); | |
| }; | |
| // Compute result | |
| const compute = () => { | |
| let computation; | |
| const prev = parseFloat(previous); | |
| const curr = parseFloat(current); | |
| if (isNaN(prev) || isNaN(curr)) return; | |
| switch (operation) { | |
| case '+': | |
| computation = prev + curr; | |
| break; | |
| case '-': | |
| computation = prev - curr; | |
| break; | |
| case '*': | |
| computation = prev * curr; | |
| break; | |
| case '/': | |
| computation = prev / curr; | |
| break; | |
| default: | |
| return; | |
| } | |
| setCurrent(computation.toString()); | |
| setOperation(null); | |
| setPrevious(null); | |
| setOverwrite(true); | |
| }; | |
| // Button Helper | |
| const Button = ({ label, onClick, className = '', variant = 'default' }) => { | |
| let bgClass = 'bg-gray-700 hover:bg-gray-600 text-white'; | |
| if (variant === 'operator') bgClass = 'bg-orange-500 hover:bg-orange-400 text-white'; | |
| if (variant === 'action') bgClass = 'bg-gray-500 hover:bg-gray-400 text-white'; | |
| if (variant === 'danger') bgClass = 'bg-red-500/80 hover:bg-red-400 text-white'; | |
| return ( | |
| <button | |
| onClick={onClick} | |
| className={`h-16 w-16 rounded-full font-bold text-xl transition-all duration-200 active:scale-95 flex items-center justify-center shadow-lg ${bgClass} ${className}`} | |
| > | |
| {label} | |
| </button> | |
| ); | |
| }; | |
| return ( | |
| <div className="flex flex-col items-center justify-center min-h-screen p-4"> | |
| <a | |
| href="https://huggingface.co/spaces/akhaliq/anycoder" | |
| target="_blank" | |
| rel="noopener noreferrer" | |
| className="mb-8 inline-flex items-center gap-2 px-4 py-2 rounded-full bg-white/10 hover:bg-white/20 text-white/80 transition-colors border border-white/10" | |
| > | |
| <span className="text-sm font-medium">Built with anycoder</span> | |
| <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"> | |
| <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M14 5l7 7m0 0l-7 7m7-7H3"></path> | |
| </svg> | |
| </a> | |
| <div className="relative bg-gray-900 rounded-3xl p-8 shadow-2xl border border-gray-800 w-full max-w-md"> | |
| {/* Glow Effect */} | |
| <div className="absolute -inset-1 bg-gradient-to-r from-blue-500/20 to-purple-500/20 rounded-3xl blur opacity-30"></div> | |
| {/* Display Area */} | |
| <div className="mb-8 flex flex-col items-end justify-end h-32"> | |
| <div className="text-gray-400 text-sm font-medium h-6 mb-2"> | |
| {previous} {operation} | |
| </div> | |
| <div className="text-white text-5xl font-light tracking-tight overflow-hidden text-ellipsis w-full text-right break-all"> | |
| {current} | |
| </div> | |
| </div> | |
| {/* Grid Controls */} | |
| <div className="grid grid-cols-4 gap-4 justify-items-center"> | |
| <Button label="AC" onClick={clear} variant="danger" /> | |
| <Button label="DEL" onClick={deleteLast} variant="action" /> | |
| <Button label="%" onClick={() => { | |
| const val = parseFloat(current); | |
| setCurrent((val / 100).toString()); | |
| setOverwrite(true); | |
| }} variant="action" /> | |
| <Button label="/" onClick={() => chooseOperation('/')} variant="operator" /> | |
| <Button label="7" onClick={() => appendNumber('7')} /> | |
| <Button label="8" onClick={() => appendNumber('8')} /> | |
| <Button label="9" onClick={() => appendNumber('9')} /> | |
| <Button label="*" onClick={() => chooseOperation('*')} variant="operator" /> | |
| <Button label="4" onClick={() => appendNumber('4')} /> | |
| <Button label="5" onClick={() => appendNumber('5')} /> | |
| <Button label="6" onClick={() => appendNumber('6')} /> | |
| <Button label="-" onClick={() => chooseOperation('-')} variant="operator" /> | |
| <Button label="1" onClick={() => appendNumber('1')} /> | |
| <Button label="2" onClick={() => appendNumber('2')} /> | |
| <Button label="3" onClick={() => appendNumber('3')} /> | |
| <Button label="+" onClick={() => chooseOperation('+')} variant="operator" /> | |
| <Button label="." onClick={appendDecimal} className="text-2xl pb-4" /> | |
| <Button label="0" onClick={() => appendNumber('0')} /> | |
| <Button label="=" onClick={compute} variant="operator" className="bg-blue-600 hover:bg-blue-500" /> | |
| </div> | |
| </div> | |
| <div className="mt-12 text-gray-500 text-sm"> | |
| Modern Calculator | |
| </div> | |
| </div> | |
| ); | |
| } |