"use client"; /** * 계산기 위젯 컴포넌트 * - 기본 사칙연산 지원 * - 실시간 계산 * - 대시보드 위젯으로 사용 가능 */ import React, { useState, useEffect } from "react"; import { Button } from "@/components/ui/button"; import { DashboardElement } from "@/components/admin/dashboard/types"; interface CalculatorWidgetProps { element?: DashboardElement; className?: string; } export default function CalculatorWidget({ element, className = "" }: CalculatorWidgetProps) { const [display, setDisplay] = useState("0"); const [previousValue, setPreviousValue] = useState(null); const [operation, setOperation] = useState(null); const [waitingForOperand, setWaitingForOperand] = useState(false); // 숫자 입력 처리 const handleNumber = (num: string) => { if (waitingForOperand) { setDisplay(num); setWaitingForOperand(false); } else { setDisplay(display === "0" ? num : display + num); } }; // 소수점 입력 const handleDecimal = () => { if (waitingForOperand) { setDisplay("0."); setWaitingForOperand(false); } else if (display.indexOf(".") === -1) { setDisplay(display + "."); } }; // 연산자 입력 const handleOperation = (nextOperation: string) => { const inputValue = parseFloat(display); if (previousValue === null) { setPreviousValue(inputValue); } else if (operation) { const currentValue = previousValue || 0; const newValue = calculate(currentValue, inputValue, operation); setDisplay(String(newValue)); setPreviousValue(newValue); } setWaitingForOperand(true); setOperation(nextOperation); }; // 계산 수행 const calculate = (firstValue: number, secondValue: number, operation: string): number => { switch (operation) { case "+": return firstValue + secondValue; case "-": return firstValue - secondValue; case "×": return firstValue * secondValue; case "÷": return secondValue !== 0 ? firstValue / secondValue : 0; default: return secondValue; } }; // 등호 처리 const handleEquals = () => { const inputValue = parseFloat(display); if (previousValue !== null && operation) { const newValue = calculate(previousValue, inputValue, operation); setDisplay(String(newValue)); setPreviousValue(null); setOperation(null); setWaitingForOperand(true); } }; // 초기화 const handleClear = () => { setDisplay("0"); setPreviousValue(null); setOperation(null); setWaitingForOperand(false); }; // 백스페이스 const handleBackspace = () => { if (!waitingForOperand) { const newDisplay = display.slice(0, -1); setDisplay(newDisplay || "0"); } }; // 부호 변경 const handleSign = () => { const value = parseFloat(display); setDisplay(String(value * -1)); }; // 퍼센트 const handlePercent = () => { const value = parseFloat(display); setDisplay(String(value / 100)); }; // 키보드 입력 처리 useEffect(() => { const handleKeyDown = (event: KeyboardEvent) => { const key = event.key; // 숫자 키 (0-9) if (/^[0-9]$/.test(key)) { event.preventDefault(); handleNumber(key); } // 연산자 키 else if (key === "+" || key === "-" || key === "*" || key === "/") { event.preventDefault(); handleOperation(key); } // 소수점 else if (key === ".") { event.preventDefault(); handleDecimal(); } // Enter 또는 = (계산) else if (key === "Enter" || key === "=") { event.preventDefault(); handleEquals(); } // Escape 또는 c (초기화) else if (key === "Escape" || key.toLowerCase() === "c") { event.preventDefault(); handleClear(); } // Backspace (지우기) else if (key === "Backspace") { event.preventDefault(); handleBackspace(); } // % (퍼센트) else if (key === "%") { event.preventDefault(); handlePercent(); } }; // 이벤트 리스너 등록 window.addEventListener("keydown", handleKeyDown); // 클린업 return () => { window.removeEventListener("keydown", handleKeyDown); }; }, [display, previousValue, operation, waitingForOperand]); return (
{/* 제목 */}

{element?.customTitle || "계산기"}

{/* 디스플레이 */}
{operation && previousValue !== null && (
{previousValue} {operation}
)}
{display}
{/* 버튼 그리드 */}
{/* 첫 번째 줄 */} {/* 두 번째 줄 */} {/* 세 번째 줄 */} {/* 네 번째 줄 */} {/* 다섯 번째 줄 */}
); }