Jayantsharma46 commited on
Commit
905014a
·
verified ·
1 Parent(s): e0cf339

Upload components/Calculator.jsx with huggingface_hub

Browse files
Files changed (1) hide show
  1. components/Calculator.jsx +217 -0
components/Calculator.jsx ADDED
@@ -0,0 +1,217 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { useState, useCallback } from 'react';
2
+
3
+ export default function Calculator() {
4
+ const [display, setDisplay] = useState('0');
5
+ const [previousValue, setPreviousValue] = useState(null);
6
+ const [operation, setOperation] = useState(null);
7
+ const [waitingForOperand, setWaitingForOperand] = useState(false);
8
+ const [history, setHistory] = useState([]);
9
+
10
+ const inputDigit = useCallback((digit) => {
11
+ if (waitingForOperand) {
12
+ setDisplay(digit);
13
+ setWaitingForOperand(false);
14
+ } else {
15
+ setDisplay(display === '0' ? digit : display + digit);
16
+ }
17
+ }, [display, waitingForOperand]);
18
+
19
+ const inputDecimal = useCallback(() => {
20
+ if (waitingForOperand) {
21
+ setDisplay('0.');
22
+ setWaitingForOperand(false);
23
+ } else if (!display.includes('.')) {
24
+ setDisplay(display + '.');
25
+ }
26
+ }, [display, waitingForOperand]);
27
+
28
+ const clear = useCallback(() => {
29
+ setDisplay('0');
30
+ setPreviousValue(null);
31
+ setOperation(null);
32
+ setWaitingForOperand(false);
33
+ }, []);
34
+
35
+ const toggleSign = useCallback(() => {
36
+ setDisplay(String(-parseFloat(display)));
37
+ }, [display]);
38
+
39
+ const percentage = useCallback(() => {
40
+ setDisplay(String(parseFloat(display) / 100));
41
+ }, [display]);
42
+
43
+ const performOperation = useCallback((nextOperation) => {
44
+ const inputValue = parseFloat(display);
45
+
46
+ if (previousValue === null) {
47
+ setPreviousValue(inputValue);
48
+ } else if (operation) {
49
+ const currentValue = previousValue || 0;
50
+ let result;
51
+
52
+ switch (operation) {
53
+ case '+':
54
+ result = currentValue + inputValue;
55
+ break;
56
+ case '-':
57
+ result = currentValue - inputValue;
58
+ break;
59
+ case '×':
60
+ result = currentValue * inputValue;
61
+ break;
62
+ case '÷':
63
+ result = currentValue / inputValue;
64
+ break;
65
+ default:
66
+ result = inputValue;
67
+ }
68
+
69
+ setDisplay(String(result));
70
+ setPreviousValue(result);
71
+
72
+ // Add to history
73
+ setHistory(prev => [...prev, `${currentValue} ${operation} ${inputValue} = ${result}`].slice(-5));
74
+ }
75
+
76
+ setWaitingForOperand(true);
77
+ setOperation(nextOperation);
78
+ }, [display, operation, previousValue]);
79
+
80
+ const calculate = useCallback(() => {
81
+ if (!operation || previousValue === null) return;
82
+
83
+ const inputValue = parseFloat(display);
84
+ let result;
85
+
86
+ switch (operation) {
87
+ case '+':
88
+ result = previousValue + inputValue;
89
+ break;
90
+ case '-':
91
+ result = previousValue - inputValue;
92
+ break;
93
+ case '×':
94
+ result = previousValue * inputValue;
95
+ break;
96
+ case '÷':
97
+ result = previousValue / inputValue;
98
+ break;
99
+ default:
100
+ result = inputValue;
101
+ }
102
+
103
+ setHistory(prev => [...prev, `${previousValue} ${operation} ${inputValue} = ${result}`].slice(-5));
104
+ setDisplay(String(result));
105
+ setPreviousValue(null);
106
+ setOperation(null);
107
+ setWaitingForOperand(true);
108
+ }, [display, operation, previousValue]);
109
+
110
+ const buttons = [
111
+ { label: 'AC', action: clear, type: 'function' },
112
+ { label: '±', action: toggleSign, type: 'function' },
113
+ { label: '%', action: percentage, type: 'function' },
114
+ { label: '÷', action: () => performOperation('÷'), type: 'operator' },
115
+ { label: '7', action: () => inputDigit('7'), type: 'number' },
116
+ { label: '8', action: () => inputDigit('8'), type: 'number' },
117
+ { label: '9', action: () => inputDigit('9'), type: 'number' },
118
+ { label: '×', action: () => performOperation('×'), type: 'operator' },
119
+ { label: '4', action: () => inputDigit('4'), type: 'number' },
120
+ { label: '5', action: () => inputDigit('5'), type: 'number' },
121
+ { label: '6', action: () => inputDigit('6'), type: 'number' },
122
+ { label: '-', action: () => performOperation('-'), type: 'operator' },
123
+ { label: '1', action: () => inputDigit('1'), type: 'number' },
124
+ { label: '2', action: () => inputDigit('2'), type: 'number' },
125
+ { label: '3', action: () => inputDigit('3'), type: 'number' },
126
+ { label: '+', action: () => performOperation('+'), type: 'operator' },
127
+ { label: '0', action: () => inputDigit('0'), type: 'number', wide: true },
128
+ { label: '.', action: inputDecimal, type: 'number' },
129
+ { label: '=', action: calculate, type: 'equals' },
130
+ ];
131
+
132
+ const getButtonClass = (btn) => {
133
+ const baseClass = 'h-14 sm:h-16 rounded-2xl font-semibold text-lg sm:text-xl transition-all duration-150 active:scale-95 flex items-center justify-center';
134
+
135
+ if (btn.type === 'operator') {
136
+ return `${baseClass} bg-gradient-to-br from-orange-500 to-orange-600 text-white shadow-lg shadow-orange-500/30 hover:shadow-orange-500/50 hover:scale-105`;
137
+ }
138
+ if (btn.type === 'equals') {
139
+ return `${baseClass} bg-gradient-to-br from-emerald-500 to-emerald-600 text-white shadow-lg shadow-emerald-500/30 hover:shadow-emerald-500/50 hover:scale-105`;
140
+ }
141
+ if (btn.type === 'function') {
142
+ return `${baseClass} bg-gradient-to-br from-slate-600 to-slate-700 text-white shadow-lg shadow-slate-600/30 hover:shadow-slate-600/50 hover:scale-105`;
143
+ }
144
+ return `${baseClass} bg-gradient-to-br from-slate-200 to-slate-300 text-slate-800 shadow-lg shadow-slate-400/20 hover:shadow-slate-400/40 hover:scale-105`;
145
+ };
146
+
147
+ return (
148
+ <div className="min-h-screen flex flex-col items-center justify-center p-4 sm:p-8">
149
+ {/* Header with branding */}
150
+ <div className="mb-8 text-center">
151
+ <h1 className="text-3xl sm:text-4xl font-bold text-transparent bg-clip-text bg-gradient-to-r from-cyan-400 via-purple-400 to-pink-400 mb-2">
152
+ Calculator
153
+ </h1>
154
+ <a
155
+ href="https://huggingface.co/spaces/akhaliq/anycoder"
156
+ target="_blank"
157
+ rel="noopener noreferrer"
158
+ className="text-xs sm:text-sm text-slate-400 hover:text-cyan-400 transition-colors"
159
+ >
160
+ Built with anycoder
161
+ </a>
162
+ </div>
163
+
164
+ <div className="w-full max-w-sm animate-scale-in">
165
+ {/* Calculator Body */}
166
+ <div className="bg-gradient-to-br from-slate-800 to-slate-900 rounded-3xl p-4 sm:p-6 shadow-2xl shadow-slate-900/50 border border-slate-700/50 backdrop-blur">
167
+
168
+ {/* Display Screen */}
169
+ <div className="bg-gradient-to-b from-slate-900 to-slate-800 rounded-2xl p-4 sm:p-6 mb-4 shadow-inner border border-slate-700/30">
170
+ <div className="text-right">
171
+ <div className="text-xs sm:text-sm text-slate-500 mb-1 h-4">
172
+ {previousValue} {operation}
173
+ </div>
174
+ <div className="text-4xl sm:text-5xl font-bold text-white truncate tracking-wider">
175
+ {display}
176
+ </div>
177
+ </div>
178
+ </div>
179
+
180
+ {/* History Strip */}
181
+ {history.length > 0 && (
182
+ <div className="mb-4 px-2">
183
+ <div className="flex gap-1 overflow-x-auto pb-2 scrollbar-hide">
184
+ {history.map((item, index) => (
185
+ <span
186
+ key={index}
187
+ className="text-xs text-slate-500 whitespace-nowrap bg-slate-800/50 px-2 py-1 rounded-lg"
188
+ >
189
+ {item}
190
+ </span>
191
+ ))}
192
+ </div>
193
+ </div>
194
+ )}
195
+
196
+ {/* Button Grid */}
197
+ <div className="grid grid-cols-4 gap-2 sm:gap-3">
198
+ {buttons.map((btn, index) => (
199
+ <button
200
+ key={index}
201
+ onClick={btn.action}
202
+ className={`${getButtonClass(btn)} ${btn.wide ? 'col-span-2' : ''}`}
203
+ >
204
+ {btn.label}
205
+ </button>
206
+ ))}
207
+ </div>
208
+ </div>
209
+
210
+ {/* Footer */}
211
+ <p className="text-center text-slate-500 text-xs mt-6">
212
+ A beautiful calculator built with React & Tailwind
213
+ </p>
214
+ </div>
215
+ </div>
216
+ );
217
+ }