diff --git a/.gitignore b/.gitignore index da8df9f..f984719 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,6 @@ node_modules .vscode/ + +# Build output +build/ +dist/ diff --git a/src/App.css b/src/App.css index 1240ef6..2936f4f 100644 --- a/src/App.css +++ b/src/App.css @@ -1,4 +1,4 @@ -/* Global Styles */ +/* ===== GLOBAL STYLES ===== */ html, body { height: 100vh; overflow: hidden; @@ -26,13 +26,12 @@ html, body { box-sizing: border-box; } -/* Tab Navigation */ +/* ===== TAB NAVIGATION ===== */ .tab-navigation { display: flex; justify-content: center; gap: 0; - margin-bottom: 40px; - margin-top: 80px; + margin: 80px 0 40px 0; } .tab-button { @@ -65,15 +64,55 @@ html, body { color: #282c34; } - -/* Tab Content */ .tab-content { width: 100%; max-width: 600px; padding: 20px; } -/* Shared Component Styles */ +/* ===== SIMULATION TAB NAVIGATION ===== */ +.simulation-tab-navigation { + display: flex; + justify-content: center; + gap: 0; + margin-bottom: 30px; +} + +.simulation-tab-button { + padding: 12px 40px; + font-size: 16px; + font-weight: bold; + background-color: #555; + color: #ffffff; + border: none; + cursor: pointer; + transition: all 0.3s ease; + border-radius: 0; + min-width: 150px; +} + +.simulation-tab-button:first-child { + border-radius: 8px 0 0 8px; +} + +.simulation-tab-button:last-child { + border-radius: 0 8px 8px 0; +} + +.simulation-tab-button:hover { + background-color: #666; +} + +.simulation-tab-button.active { + background-color: #61dafb; + color: #282c34; +} + +.simulation-tab-content { + width: 100%; +} + +/* ===== SHARED COMPONENTS ===== */ .component-container { width: 600px; max-width: 100%; @@ -81,7 +120,112 @@ html, body { text-align: center; } -/* Textarea styles */ +/* ===== BUTTONS ===== */ +.component-button { + padding: 15px 40px; + font-size: 16px; + background-color: #61dafb; + color: #282c34; + border: none; + border-radius: 8px; + cursor: pointer; + font-weight: bold; + transition: background-color 0.3s ease; + width: 180px; + white-space: nowrap; +} + +.component-button:hover { + background-color: #21a1c4; +} + +.button-row { + display: flex; + gap: 12px; + align-items: center; + justify-content: center; + margin: 16px 0; +} + +/* Loading Button States */ +.loading-button { + position: relative; + overflow: hidden; + transition: all 0.3s ease; +} + +.loading-button.loading { + background-color: #666 !important; + cursor: not-allowed; +} + +.loading-button.success { + background-color: #4CAF50 !important; + animation: successPulse 0.6s ease-out; + min-width: 180px; + width: 180px; +} + +.loading-button.error { + background-color: #f44336 !important; + color: white !important; + animation: errorPulse 0.6s ease-out; + min-width: 180px; + width: 180px; +} + +.loading-button.disabled { + background-color: #444 !important; + cursor: not-allowed; + opacity: 0.6; +} + +.button-content { + display: flex; + align-items: center; + justify-content: center; + gap: 8px; + width: 100%; + min-height: 24px; +} + +.loading-content .spinner { + width: 16px; + height: 16px; + border: 2px solid transparent; + border-top: 2px solid currentColor; + border-radius: 50%; + animation: spin 1s linear infinite; +} + +.success-content .success-icon { + animation: bounceIn 0.6s ease-out; +} + +/* Copy Button */ +.copy-button { + background: rgba(255, 255, 255, 0.1); + border: 1px solid rgba(255, 255, 255, 0.2); + border-radius: 6px; + color: #4CAF50; + cursor: pointer; + padding: 8px 12px; + font-size: 14px; + transition: all 0.2s ease; + position: relative; +} + +.copy-button:hover { + background: rgba(255, 255, 255, 0.15); + transform: translateY(-1px); + box-shadow: 0 2px 8px rgba(76, 175, 80, 0.3); +} + +.copy-button:active { + transform: translateY(0); +} + +/* ===== TEXTAREAS & INPUTS ===== */ .base-textarea { padding: 15px; font-size: 14px; @@ -103,25 +247,32 @@ html, body { max-height: 15vh; } -.component-button { - padding: 15px 40px; - font-size: 16px; - background-color: #61dafb; - color: #282c34; - border: none; +.encode-textarea { + min-height: 50vh; + max-height: 70vh; +} + +.foundry-input-white { + width: 100%; + padding: 12px; + font-size: 14px; border-radius: 8px; - cursor: pointer; - font-weight: bold; - transition: background-color 0.3s ease; - width: 180px; - white-space: nowrap; + border: 1px solid #555; + background-color: #ffffff; + color: #333; + font-family: monospace; + transition: border-color 0.3s ease; + height: 40px; + box-sizing: border-box; } -.component-button:hover { - background-color: #21a1c4; +.foundry-input-white:focus { + outline: none; + border-color: #61dafb; + box-shadow: 0 0 8px rgba(97, 218, 251, 0.3); } -/* Result container styles */ +/* ===== RESULT DISPLAYS ===== */ .base-result-container { margin-top: 20px; padding: 15px; @@ -139,8 +290,10 @@ html, body { overflow-y: auto; } +.encode-result-container { + min-height: 60px; +} -/* Result content styles */ .base-result-content { color: #ffffff; font-size: 11px; @@ -155,76 +308,65 @@ html, body { overflow: visible; } -/* Encode Component Styles */ -.encode-textarea { - min-height: 50vh; - max-height: 70vh; -} - -.encode-result-container { - min-height: 60px; -} - .encode-result-content { max-height: 120px; overflow: auto; } -/* Toast Notifications */ -.toast { - position: fixed; - top: 30px; - left: 50%; - transform: translateX(-50%); - color: white; - padding: 12px 20px; - border-radius: 8px; - font-size: 14px; +.result-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 4px; + padding-bottom: 4px; + border-bottom: 1px solid #333; +} + +.result-title { + color: #61dafb; font-weight: bold; - box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3); - z-index: 1000; - animation: slideDown 0.3s ease-out; + font-size: 14px; } -.toast.success { - background-color: #4CAF50; +.result-actions { + display: flex; + gap: 8px; + align-items: center; } -.toast.error { - background-color: #f44336; - border: 2px solid #d32f2f; - box-shadow: 0 4px 12px rgba(244, 67, 54, 0.3); - font-weight: bold; +.result-actions .copy-button, +.result-actions .edit-button, +.result-actions .simulate-button { + min-width: 60px; + height: 32px; + padding: 6px 12px; + display: flex; + align-items: center; + justify-content: center; + font-size: 14px; } -/* Encode Layout */ -.encode-layout { - position: relative; - width: 100%; - height: 100%; +.result-actions .copy-button { + color: #4CAF50; + border-color: rgba(76, 175, 80, 0.3); } -.encode-examples-section { - position: fixed; - left: 1%; - top: 50%; - transform: translateY(-50%); - width: 25%; - max-height: calc(100vh - 100px); - overflow-y: auto; - z-index: 10; +.result-actions .copy-button:hover { + box-shadow: 0 2px 8px rgba(76, 175, 80, 0.3); } -.encode-main-section { - width: 100%; - height: 100%; - display: flex; - justify-content: center; - align-items: center; +.result-actions .edit-button, +.result-actions .simulate-button { + color: #FF9800; + border-color: rgba(255, 152, 0, 0.3); } +.result-actions .edit-button:hover, +.result-actions .simulate-button:hover { + box-shadow: 0 2px 8px rgba(255, 152, 0, 0.3); +} -/* Form Components */ +/* ===== FORMS ===== */ .form-row { display: flex; gap: 20px; @@ -254,32 +396,10 @@ html, body { font-weight: bold; } -.foundry-input-white { - width: 100%; - padding: 12px; - font-size: 14px; - border-radius: 8px; - border: 1px solid #555; - background-color: #ffffff; - color: #333; - font-family: monospace; - transition: border-color 0.3s ease; - height: 40px; - box-sizing: border-box; -} - -.foundry-input-white:focus { - outline: none; - border-color: #61dafb; - box-shadow: 0 0 8px rgba(97, 218, 251, 0.3); -} - -/* Simulation Components */ .submit-section { margin-top: 20px; } - .api-key-info { font-size: 12px; color: #6c757d; @@ -298,6 +418,33 @@ html, body { text-decoration: underline; } +/* ===== ENCODE LAYOUT ===== */ +.encode-layout { + position: relative; + width: 100%; + height: 100%; +} + +.encode-examples-section { + position: fixed; + left: 1%; + top: 50%; + transform: translateY(-50%); + width: 25%; + max-height: calc(100vh - 100px); + overflow-y: auto; + z-index: 10; +} + +.encode-main-section { + width: 100%; + height: 100%; + display: flex; + justify-content: center; + align-items: center; +} + +/* ===== SIMULATION COMPONENTS ===== */ .simulation-success-card { margin-top: 20px; } @@ -361,50 +508,34 @@ html, body { text-decoration: none; } -/* Responsive Design */ -@media (max-width: 1200px) { - .encode-layout { - display: flex; - flex-direction: column; - gap: 16px; - } - - .encode-examples-section { - position: static; - transform: none; - width: 100%; - max-width: 100%; - min-width: auto; - max-height: 400px; - left: auto; - top: auto; - order: 2; - } - - .encode-main-section { - order: 1; - display: block; - } +/* ===== TOAST NOTIFICATIONS ===== */ +.toast { + position: fixed; + top: 30px; + left: 50%; + transform: translateX(-50%); + color: white; + padding: 12px 20px; + border-radius: 8px; + font-size: 14px; + font-weight: bold; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3); + z-index: 1000; + animation: slideDown 0.3s ease-out; } -@media (max-width: 1024px) { - .encode-examples-section { - max-height: 350px; - } +.toast.success { + background-color: #4CAF50; } -@media (max-width: 768px) { - .encode-examples-section { - max-height: 300px; - } - - .form-row { - flex-direction: column; - gap: 0; - } +.toast.error { + background-color: #f44336; + border: 2px solid #d32f2f; + box-shadow: 0 4px 12px rgba(244, 67, 54, 0.3); + font-weight: bold; } - +/* ===== ANIMATIONS ===== */ @keyframes slideDown { from { transform: translateX(-50%) translateY(-20px); @@ -416,148 +547,6 @@ html, body { } } - -/* Loading Button Styles */ -.loading-button { - position: relative; - overflow: hidden; - transition: all 0.3s ease; -} - -.loading-button.loading { - background-color: #666 !important; - cursor: not-allowed; -} - -.loading-button.success { - background-color: #4CAF50 !important; - animation: successPulse 0.6s ease-out; - min-width: 180px; - width: 180px; -} - -.loading-button.error { - background-color: #f44336 !important; - color: white !important; - animation: errorPulse 0.6s ease-out; - min-width: 180px; - width: 180px; -} - -.loading-button.disabled { - background-color: #444 !important; - cursor: not-allowed; - opacity: 0.6; -} - -.button-content { - display: flex; - align-items: center; - justify-content: center; - gap: 8px; - width: 100%; - min-height: 24px; -} - -.loading-content .spinner { - width: 16px; - height: 16px; - border: 2px solid transparent; - border-top: 2px solid currentColor; - border-radius: 50%; - animation: spin 1s linear infinite; -} - -.success-content .success-icon { - animation: bounceIn 0.6s ease-out; -} - -/* Copy Button Styles */ -.copy-button { - background: rgba(255, 255, 255, 0.1); - border: 1px solid rgba(255, 255, 255, 0.2); - border-radius: 6px; - color: #4CAF50; - cursor: pointer; - padding: 8px 12px; - font-size: 14px; - transition: all 0.2s ease; - position: relative; -} - -.copy-button:hover { - background: rgba(255, 255, 255, 0.15); - transform: translateY(-1px); - box-shadow: 0 2px 8px rgba(76, 175, 80, 0.3); -} - -.copy-button:active { - transform: translateY(0); -} - - -/* Button Row Styles */ -.button-row { - display: flex; - gap: 12px; - align-items: center; - justify-content: center; - margin: 16px 0; -} - - -/* Result Header Styles */ -.result-header { - display: flex; - justify-content: space-between; - align-items: center; - margin-bottom: 4px; - padding-bottom: 4px; - border-bottom: 1px solid #333; -} - -.result-title { - color: #61dafb; - font-weight: bold; - font-size: 14px; -} - -.result-actions { - display: flex; - gap: 8px; - align-items: center; -} - -.result-actions .copy-button, -.result-actions .edit-button { - min-width: 60px; - height: 32px; - padding: 6px 12px; - display: flex; - align-items: center; - justify-content: center; - font-size: 14px; -} - -.result-actions .copy-button { - color: #4CAF50; - border-color: rgba(76, 175, 80, 0.3); -} - -.result-actions .copy-button:hover { - box-shadow: 0 2px 8px rgba(76, 175, 80, 0.3); -} - -.result-actions .edit-button { - color: #FF9800; - border-color: rgba(255, 152, 0, 0.3); -} - -.result-actions .edit-button:hover { - box-shadow: 0 2px 8px rgba(255, 152, 0, 0.3); -} - -/* Button Animations */ @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } @@ -581,11 +570,50 @@ html, body { 100% { transform: scale(1); opacity: 1; } } -/* Responsive adjustments for new components */ +/* ===== RESPONSIVE DESIGN ===== */ +@media (max-width: 1200px) { + .encode-layout { + display: flex; + flex-direction: column; + gap: 16px; + } + + .encode-examples-section { + position: static; + transform: none; + width: 100%; + max-width: 100%; + min-width: auto; + max-height: 400px; + left: auto; + top: auto; + order: 2; + } + + .encode-main-section { + order: 1; + display: block; + } +} + +@media (max-width: 1024px) { + .encode-examples-section { + max-height: 350px; + } +} + @media (max-width: 768px) { + .encode-examples-section { + max-height: 300px; + } + + .form-row { + flex-direction: column; + gap: 0; + } + .button-row { flex-direction: column; gap: 8px; } - } \ No newline at end of file diff --git a/src/App.js b/src/App.js index 22fd202..97e23bc 100644 --- a/src/App.js +++ b/src/App.js @@ -6,7 +6,7 @@ import { validateEncodedCalldata, validateDecodedJson } from './utils/core/round import { createDecodeOperation, createEncodeOperation, formatJSON } from './utils/componentUtils.js'; import DecodeCalldata from './components/forms/DecodeCalldata'; import EncodeCalldata from './components/forms/EncodeCalldata'; -import SimulateTX from './components/SimulateTX'; +import SimulateTX from './components/simulate/SimulateTX'; function App() { const [activeTab, setActiveTab] = useState('decode'); @@ -66,6 +66,13 @@ function App() { showToast('Switched to Encode tab with decoded result!', 'success'); }; + const handleSimulateFromEncode = (calldata) => { + // Navigate to simulate tab and populate with encoded calldata + setActiveTab('simulate'); + updateSimulationFormData('calldata', calldata); + showToast('Switched to Simulate TX tab with encoded calldata!', 'success'); + }; + return (
Analyze your transaction simulation with detailed traces and logs
-Analyze your transaction simulation with detailed traces and logs
+