Spaces:
Running
Running
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>Forward Contract Dashboard</title> | |
<script src="https://cdn.tailwindcss.com"></script> | |
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> | |
<style> | |
/* Custom CSS for floating windows */ | |
.floating-window { | |
position: fixed; | |
bottom: 30px; | |
right: 30px; | |
width: 350px; | |
background: white; | |
border-radius: 15px; | |
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2); | |
z-index: 1000; | |
transform: translateY(100px); | |
opacity: 0; | |
transition: all 0.3s ease; | |
} | |
.floating-window.active { | |
transform: translateY(0); | |
opacity: 1; | |
} | |
.floating-btn { | |
position: fixed; | |
width: 60px; | |
height: 60px; | |
background: linear-gradient(135deg, #3b82f6, #1d4ed8); | |
color: white; | |
border-radius: 50%; | |
display: flex; | |
justify-content: center; | |
align-items: center; | |
cursor: pointer; | |
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2); | |
z-index: 1001; | |
} | |
#trade-btn { | |
bottom: 30px; | |
right: 30px; | |
} | |
#supplier-btn { | |
bottom: 110px; | |
right: 30px; | |
background: linear-gradient(135deg, #10b981, #059669); | |
} | |
.tab-content { | |
display: none; | |
} | |
.tab-content.active { | |
display: block; | |
} | |
.chart-container { | |
height: 300px; | |
position: relative; | |
} | |
.spinner { | |
border: 4px solid rgba(0, 0, 0, 0.1); | |
border-radius: 50%; | |
border-top: 4px solid #3b82f6; | |
width: 40px; | |
height: 40px; | |
animation: spin 1s linear infinite; | |
margin: 20px auto; | |
} | |
@keyframes spin { | |
0% { transform: rotate(0deg); } | |
100% { transform: rotate(360deg); } | |
} | |
.price-up { | |
color: #10b981; | |
} | |
.price-down { | |
color: #ef4444; | |
} | |
.blurred { | |
filter: blur(5px); | |
user-select: none; | |
} | |
.fee-tier { | |
border-left: 3px solid #3b82f6; | |
padding-left: 10px; | |
margin-bottom: 15px; | |
} | |
.profit-calc { | |
background-color: #f0fdf4; | |
border-radius: 8px; | |
padding: 15px; | |
margin-top: 15px; | |
} | |
</style> | |
</head> | |
<body class="bg-gray-50"> | |
<div class="container mx-auto px-4 py-8"> | |
<header class="mb-8"> | |
<div class="flex justify-between items-center"> | |
<h1 class="text-3xl font-bold text-gray-800">Cotton Commodity Dashboard</h1> | |
<div class="flex items-center space-x-4"> | |
<span class="text-sm text-gray-600">Last updated: <span id="update-time">Just now</span></span> | |
<button id="refresh-btn" class="bg-blue-500 hover:bg-blue-600 text-white px-4 py-2 rounded-lg flex items-center"> | |
<i class="fas fa-sync-alt mr-2"></i> Refresh | |
</button> | |
</div> | |
</div> | |
<p class="text-gray-600 mt-2">Real-time cotton prices, forecasts, and trading options</p> | |
</header> | |
<div class="grid grid-cols-1 lg:grid-cols-3 gap-6 mb-8"> | |
<!-- Current Price Card --> | |
<div class="bg-white rounded-xl shadow-md p-6"> | |
<div class="flex justify-between items-start"> | |
<div> | |
<h2 class="text-lg font-semibold text-gray-700">Current Price</h2> | |
<div class="mt-2 flex items-end"> | |
<span id="current-price" class="text-3xl font-bold text-gray-900">0.85</span> | |
<span class="ml-2 text-lg font-medium">USD/lb</span> | |
</div> | |
</div> | |
<div id="price-change" class="px-3 py-1 rounded-full bg-green-100 text-green-800 flex items-center"> | |
<i class="fas fa-caret-up mr-1"></i> | |
<span>+0.02 (2.4%)</span> | |
</div> | |
</div> | |
<div class="mt-4 pt-4 border-t border-gray-100"> | |
<div class="grid grid-cols-2 gap-4"> | |
<div> | |
<p class="text-sm text-gray-500">Open</p> | |
<p class="font-medium">0.83</p> | |
</div> | |
<div> | |
<p class="text-sm text-gray-500">High</p> | |
<p class="font-medium">0.86</p> | |
</div> | |
<div> | |
<p class="text-sm text-gray-500">Low</p> | |
<p class="font-medium">0.82</p> | |
</div> | |
<div> | |
<p class="text-sm text-gray-500">Volume</p> | |
<p class="font-medium">12.5K</p> | |
</div> | |
</div> | |
</div> | |
</div> | |
<!-- Market Sentiment Card --> | |
<div class="bg-white rounded-xl shadow-md p-6"> | |
<h2 class="text-lg font-semibold text-gray-700 mb-4">Market Sentiment</h2> | |
<div class="flex items-center justify-between mb-3"> | |
<span class="text-sm font-medium">Bullish</span> | |
<span class="text-sm font-medium">65%</span> | |
</div> | |
<div class="w-full bg-gray-200 rounded-full h-2.5"> | |
<div class="bg-green-500 h-2.5 rounded-full" style="width: 65%"></div> | |
</div> | |
<div class="mt-6"> | |
<h3 class="text-sm font-medium text-gray-700 mb-2">Key Factors</h3> | |
<ul class="space-y-2"> | |
<li class="flex items-start"> | |
<i class="fas fa-check-circle text-green-500 mt-1 mr-2"></i> | |
<span class="text-sm">Strong demand from textile industry</span> | |
</li> | |
<li class="flex items-start"> | |
<i class="fas fa-check-circle text-green-500 mt-1 mr-2"></i> | |
<span class="text-sm">Lower production in key regions</span> | |
</li> | |
<li class="flex items-start"> | |
<i class="fas fa-exclamation-triangle text-yellow-500 mt-1 mr-2"></i> | |
<span class="text-sm">Potential weather disruptions</span> | |
</li> | |
</ul> | |
</div> | |
</div> | |
<!-- Forecast Card --> | |
<div class="bg-white rounded-xl shadow-md p-6"> | |
<h2 class="text-lg font-semibold text-gray-700 mb-4">3-Month Forecast</h2> | |
<div class="flex items-center justify-between mb-2"> | |
<span class="text-sm font-medium">Low Estimate</span> | |
<span class="text-sm font-medium text-blue-600">0.78 USD/lb</span> | |
</div> | |
<div class="flex items-center justify-between mb-2"> | |
<span class="text-sm font-medium">Median Estimate</span> | |
<span class="text-sm font-medium text-blue-600">0.87 USD/lb</span> | |
</div> | |
<div class="flex items-center justify-between mb-4"> | |
<span class="text-sm font-medium">High Estimate</span> | |
<span class="text-sm font-medium text-blue-600">0.95 USD/lb</span> | |
</div> | |
<div class="mt-4 pt-4 border-t border-gray-100"> | |
<h3 class="text-sm font-medium text-gray-700 mb-2">Analyst Consensus</h3> | |
<p class="text-sm text-gray-600">Most analysts expect prices to remain stable with moderate upside potential due to constrained supply and steady demand growth in Asian markets.</p> | |
</div> | |
</div> | |
</div> | |
<!-- Chart Section --> | |
<div class="bg-white rounded-xl shadow-md p-6 mb-8"> | |
<div class="flex justify-between items-center mb-6"> | |
<h2 class="text-xl font-semibold text-gray-800">Price History</h2> | |
<div class="flex space-x-2"> | |
<button class="time-btn active px-3 py-1 bg-blue-500 text-white rounded-lg" data-period="1M">1M</button> | |
<button class="time-btn px-3 py-1 bg-gray-200 text-gray-700 rounded-lg" data-period="3M">3M</button> | |
<button class="time-btn px-3 py-1 bg-gray-200 text-gray-700 rounded-lg" data-period="6M">6M</button> | |
<button class="time-btn px-3 py-1 bg-gray-200 text-gray-700 rounded-lg" data-period="1Y">1Y</button> | |
</div> | |
</div> | |
<div class="chart-container"> | |
<canvas id="price-chart"></canvas> | |
</div> | |
</div> | |
<!-- News Section --> | |
<div class="bg-white rounded-xl shadow-md p-6"> | |
<h2 class="text-xl font-semibold text-gray-800 mb-6">Market News</h2> | |
<div class="space-y-4"> | |
<div class="p-4 border border-gray-100 rounded-lg hover:bg-gray-50 transition"> | |
<h3 class="font-medium text-blue-600">USDA Reports Lower Cotton Stocks</h3> | |
<p class="text-sm text-gray-600 mt-1">The USDA's latest report shows cotton stocks at their lowest level in 3 years, supporting higher prices in the near term.</p> | |
<div class="flex items-center mt-2 text-xs text-gray-500"> | |
<span>2 hours ago</span> | |
<span class="mx-2">•</span> | |
<span>Bloomberg</span> | |
</div> | |
</div> | |
<div class="p-4 border border-gray-100 rounded-lg hover:bg-gray-50 transition"> | |
<h3 class="font-medium text-blue-600">India Cotton Production Expected to Drop 15%</h3> | |
<p class="text-sm text-gray-600 mt-1">Unfavorable weather conditions in major growing regions may lead to significant production declines in the world's second-largest producer.</p> | |
<div class="flex items-center mt-2 text-xs text-gray-500"> | |
<span>5 hours ago</span> | |
<span class="mx-2">•</span> | |
<span>Reuters</span> | |
</div> | |
</div> | |
<div class="p-4 border border-gray-100 rounded-lg hover:bg-gray-50 transition"> | |
<h3 class="font-medium text-blue-600">Vietnam Textile Exports Surge in Q2</h3> | |
<p class="text-sm text-gray-600 mt-1">Increased demand from European markets is driving Vietnam's textile exports, creating additional demand for cotton imports.</p> | |
<div class="flex items-center mt-2 text-xs text-gray-500"> | |
<span>1 day ago</span> | |
<span class="mx-2">•</span> | |
<span>CNBC</span> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
<!-- Floating Buttons --> | |
<div class="floating-btn" id="trade-btn"> | |
<i class="fas fa-shopping-cart text-xl"></i> | |
</div> | |
<div class="floating-btn" id="supplier-btn"> | |
<i class="fas fa-truck text-xl"></i> | |
</div> | |
<!-- Trade Floating Window --> | |
<div class="floating-window" id="trade-window"> | |
<div class="bg-gray-800 text-white px-4 py-3 rounded-t-lg flex justify-between items-center"> | |
<h3 class="font-medium">Trade Cotton</h3> | |
<button id="close-window" class="text-gray-300 hover:text-white"> | |
<i class="fas fa-times"></i> | |
</button> | |
</div> | |
<div class="p-4"> | |
<div class="flex border-b border-gray-200"> | |
<button class="tab-btn active px-4 py-2 font-medium text-blue-600 border-b-2 border-blue-600" data-tab="buy">Buy</button> | |
<button class="tab-btn px-4 py-2 font-medium text-gray-500" data-tab="convert">Convert</button> | |
</div> | |
<div class="tab-content active" id="buy-tab"> | |
<div class="mt-4"> | |
<label class="block text-sm font-medium text-gray-700 mb-1">Payment Method</label> | |
<div class="grid grid-cols-2 gap-2 mb-4"> | |
<button class="crypto-btn active py-2 px-3 bg-blue-100 text-blue-700 rounded-lg border border-blue-200 flex items-center justify-center" data-crypto="btc"> | |
<i class="fab fa-bitcoin mr-2"></i> Bitcoin | |
</button> | |
<button class="crypto-btn py-2 px-3 bg-gray-100 text-gray-700 rounded-lg border border-gray-200 flex items-center justify-center" data-crypto="bch"> | |
<i class="fas fa-money-bill-wave mr-2"></i> Bitcoin Cash | |
</button> | |
</div> | |
<div class="mb-4"> | |
<label class="block text-sm font-medium text-gray-700 mb-1">Amount (lbs)</label> | |
<div class="relative"> | |
<input type="number" id="cotton-amount" class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-blue-500 focus:border-blue-500" value="100" min="10" step="10"> | |
<div class="absolute inset-y-0 right-0 flex items-center pr-3 pointer-events-none"> | |
<span class="text-gray-500">lbs</span> | |
</div> | |
</div> | |
</div> | |
<div class="bg-gray-50 p-3 rounded-lg mb-4"> | |
<div class="flex justify-between mb-2"> | |
<span class="text-sm text-gray-600">Price per lb</span> | |
<span class="text-sm font-medium" id="crypto-price">0.0000023 BTC</span> | |
</div> | |
<div class="flex justify-between mb-2"> | |
<span class="text-sm text-gray-600">Total Cost</span> | |
<span class="text-sm font-medium" id="total-cost">0.00023 BTC</span> | |
</div> | |
<div class="flex justify-between"> | |
<span class="text-sm text-gray-600">Equivalent</span> | |
<span class="text-sm font-medium" id="fiat-equivalent">≈ $85.00</span> | |
</div> | |
</div> | |
<button class="w-full bg-blue-600 hover:bg-blue-700 text-white py-3 rounded-lg font-medium flex items-center justify-center"> | |
<i class="fas fa-lock mr-2"></i> Confirm Purchase | |
</button> | |
</div> | |
</div> | |
<div class="tab-content" id="convert-tab"> | |
<div class="mt-4"> | |
<div class="mb-4"> | |
<label class="block text-sm font-medium text-gray-700 mb-1">From</label> | |
<div class="relative"> | |
<select class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-blue-500 focus:border-blue-500 appearance-none"> | |
<option>US Dollar (USD)</option> | |
<option>Bitcoin (BTC)</option> | |
<option>Bitcoin Cash (BCH)</option> | |
<option>Ethereum (ETH)</option> | |
</select> | |
<div class="absolute inset-y-0 right-0 flex items-center pr-3 pointer-events-none"> | |
<i class="fas fa-chevron-down text-gray-400"></i> | |
</div> | |
</div> | |
</div> | |
<div class="mb-4"> | |
<label class="block text-sm font-medium text-gray-700 mb-1">To</label> | |
<div class="relative"> | |
<select class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-blue-500 focus:border-blue-500 appearance-none"> | |
<option>Bitcoin (BTC)</option> | |
<option>Bitcoin Cash (BCH)</option> | |
<option>US Dollar (USD)</option> | |
<option>Ethereum (ETH)</option> | |
</select> | |
<div class="absolute inset-y-0 right-0 flex items-center pr-3 pointer-events-none"> | |
<i class="fas fa-chevron-down text-gray-400"></i> | |
</div> | |
</div> | |
</div> | |
<div class="mb-4"> | |
<label class="block text-sm font-medium text-gray-700 mb-1">Amount</label> | |
<input type="number" class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-blue-500 focus:border-blue-500" value="100"> | |
</div> | |
<div class="bg-gray-50 p-3 rounded-lg mb-4"> | |
<div class="flex justify-between"> | |
<span class="text-sm text-gray-600">Exchange Rate</span> | |
<span class="text-sm font-medium">1 BTC = 37,000 USD</span> | |
</div> | |
<div class="flex justify-between mt-2"> | |
<span class="text-sm text-gray-600">You Receive</span> | |
<span class="text-sm font-medium">0.0027 BTC</span> | |
</div> | |
</div> | |
<button class="w-full bg-blue-600 hover:bg-blue-700 text-white py-3 rounded-lg font-medium flex items-center justify-center"> | |
<i class="fas fa-exchange-alt mr-2"></i> Convert Now | |
</button> | |
</div> | |
</div> | |
</div> | |
</div> | |
<!-- Supplier Floating Window --> | |
<div class="floating-window" id="supplier-window"> | |
<div class="bg-green-700 text-white px-4 py-3 rounded-t-lg flex justify-between items-center"> | |
<h3 class="font-medium">Supplier Agreement</h3> | |
<button id="close-supplier-window" class="text-gray-300 hover:text-white"> | |
<i class="fas fa-times"></i> | |
</button> | |
</div> | |
<div class="p-4"> | |
<div class="mb-4"> | |
<label class="block text-sm font-medium text-gray-700 mb-1">Current Spot Price</label> | |
<div class="bg-gray-100 p-3 rounded-lg"> | |
<div class="flex justify-between items-center"> | |
<span class="font-medium">0.85 USD/lb</span> | |
<span class="text-sm text-gray-600">Updated: Just now</span> | |
</div> | |
</div> | |
</div> | |
<div class="mb-4"> | |
<label class="block text-sm font-medium text-gray-700 mb-1">Amount to Sell (lbs)</label> | |
<div class="relative"> | |
<input type="number" id="supply-amount" class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-green-500 focus:border-green-500" value="1000" min="100" step="100"> | |
<div class="absolute inset-y-0 right-0 flex items-center pr-3 pointer-events-none"> | |
<span class="text-gray-500">lbs</span> | |
</div> | |
</div> | |
</div> | |
<div class="mb-4"> | |
<label class="block text-sm font-medium text-gray-700 mb-2">Fee Structure</label> | |
<div class="space-y-3"> | |
<div class="fee-tier"> | |
<div class="flex justify-between"> | |
<span class="text-sm font-medium">First 1,000 lbs</span> | |
<span class="text-sm font-medium">$0.015/lb</span> | |
</div> | |
<p class="text-xs text-gray-500">Base fee for small suppliers</p> | |
</div> | |
<div class="fee-tier"> | |
<div class="flex justify-between"> | |
<span class="text-sm font-medium">1,001 - 10,000 lbs</span> | |
<span class="text-sm font-medium">$0.012/lb</span> | |
</div> | |
<p class="text-xs text-gray-500">Mid-tier volume discount</p> | |
</div> | |
<div class="fee-tier"> | |
<div class="flex justify-between"> | |
<span class="text-sm font-medium">10,001+ lbs</span> | |
<span class="text-sm font-medium">$0.009/lb</span> | |
</div> | |
<p class="text-xs text-gray-500">High volume discount</p> | |
</div> | |
</div> | |
</div> | |
<div class="profit-calc"> | |
<h4 class="text-sm font-medium text-gray-700 mb-2">Estimated Earnings</h4> | |
<div class="space-y-2"> | |
<div class="flex justify-between"> | |
<span class="text-sm">Gross Revenue</span> | |
<span class="text-sm font-medium" id="gross-revenue">$850.00</span> | |
</div> | |
<div class="flex justify-between"> | |
<span class="text-sm">Total Fees</span> | |
<span class="text-sm font-medium" id="total-fees">$12.00</span> | |
</div> | |
<div class="flex justify-between border-t border-gray-200 pt-2"> | |
<span class="text-sm font-medium">Net Earnings</span> | |
<span class="text-sm font-medium text-green-600" id="net-earnings">$838.00</span> | |
</div> | |
</div> | |
<div class="mt-4"> | |
<h4 class="text-sm font-medium text-gray-700 mb-2">Break-Even Analysis</h4> | |
<div class="space-y-2"> | |
<div class="flex justify-between"> | |
<span class="text-sm">Your Production Cost</span> | |
<span class="text-sm font-medium" id="production-cost">$0.00/lb</span> | |
</div> | |
<div class="flex justify-between"> | |
<span class="text-sm">Break-Even Price</span> | |
<span class="text-sm font-medium" id="break-even-price">$0.00/lb</span> | |
</div> | |
<div class="flex justify-between"> | |
<span class="text-sm">Profit Margin</span> | |
<span class="text-sm font-medium text-green-600" id="profit-margin">0%</span> | |
</div> | |
</div> | |
</div> | |
</div> | |
<div class="mt-4"> | |
<div class="flex items-start"> | |
<input type="checkbox" id="agree-terms" class="mt-1"> | |
<label for="agree-terms" class="ml-2 text-sm text-gray-700">I agree to sell my cotton at the current spot price, minus applicable fees, and understand this is a binding contract.</label> | |
</div> | |
</div> | |
<button id="confirm-supply" class="w-full bg-green-600 hover:bg-green-700 text-white py-3 rounded-lg font-medium flex items-center justify-center mt-4"> | |
<i class="fas fa-file-contract mr-2"></i> Confirm Supply Agreement | |
</button> | |
</div> | |
</div> | |
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script> | |
<script> | |
// Initialize the floating windows | |
const tradeBtn = document.getElementById('trade-btn'); | |
const tradeWindow = document.getElementById('trade-window'); | |
const closeWindow = document.getElementById('close-window'); | |
const supplierBtn = document.getElementById('supplier-btn'); | |
const supplierWindow = document.getElementById('supplier-window'); | |
const closeSupplierWindow = document.getElementById('close-supplier-window'); | |
tradeBtn.addEventListener('click', () => { | |
tradeWindow.classList.toggle('active'); | |
supplierWindow.classList.remove('active'); | |
}); | |
supplierBtn.addEventListener('click', () => { | |
supplierWindow.classList.toggle('active'); | |
tradeWindow.classList.remove('active'); | |
calculateSupplierEarnings(); // Calculate when window opens | |
}); | |
closeWindow.addEventListener('click', () => { | |
tradeWindow.classList.remove('active'); | |
}); | |
closeSupplierWindow.addEventListener('click', () => { | |
supplierWindow.classList.remove('active'); | |
}); | |
// Tab functionality | |
const tabBtns = document.querySelectorAll('.tab-btn'); | |
tabBtns.forEach(btn => { | |
btn.addEventListener('click', () => { | |
// Remove active class from all buttons and tabs | |
tabBtns.forEach(b => b.classList.remove('active', 'text-blue-600', 'border-blue-600')); | |
document.querySelectorAll('.tab-content').forEach(tab => tab.classList.remove('active')); | |
// Add active class to clicked button | |
btn.classList.add('active', 'text-blue-600', 'border-blue-600'); | |
// Show corresponding tab | |
const tabId = btn.getAttribute('data-tab') + '-tab'; | |
document.getElementById(tabId).classList.add('active'); | |
}); | |
}); | |
// Crypto selection | |
const cryptoBtns = document.querySelectorAll('.crypto-btn'); | |
cryptoBtns.forEach(btn => { | |
btn.addEventListener('click', () => { | |
cryptoBtns.forEach(b => b.classList.remove('active', 'bg-blue-100', 'text-blue-700', 'border-blue-200')); | |
btn.classList.add('active', 'bg-blue-100', 'text-blue-700', 'border-blue-200'); | |
// Update prices based on selected crypto | |
updateCryptoPrices(btn.getAttribute('data-crypto')); | |
}); | |
}); | |
function updateCryptoPrices(crypto) { | |
// These would normally come from an API | |
const prices = { | |
btc: { price: 0.0000023, symbol: 'BTC' }, | |
bch: { price: 0.00012, symbol: 'BCH' } | |
}; | |
const selected = prices[crypto]; | |
const amount = document.getElementById('cotton-amount').value; | |
const total = (amount * selected.price).toFixed(6); | |
const usdValue = (amount * 0.85).toFixed(2); | |
document.getElementById('crypto-price').textContent = `${selected.price} ${selected.symbol}`; | |
document.getElementById('total-cost').textContent = `${total} ${selected.symbol}`; | |
document.getElementById('fiat-equivalent').textContent = `≈ $${usdValue}`; | |
} | |
// Update calculations when amount changes | |
document.getElementById('cotton-amount').addEventListener('input', function() { | |
const activeCrypto = document.querySelector('.crypto-btn.active').getAttribute('data-crypto'); | |
updateCryptoPrices(activeCrypto); | |
}); | |
// Supplier calculations | |
function calculateSupplierEarnings() { | |
const amount = parseFloat(document.getElementById('supply-amount').value); | |
const spotPrice = 0.85; // Current spot price | |
// Calculate fees based on tiered structure | |
let fees = 0; | |
if (amount <= 1000) { | |
fees = amount * 0.015; | |
} else if (amount <= 10000) { | |
fees = (1000 * 0.015) + ((amount - 1000) * 0.012); | |
} else { | |
fees = (1000 * 0.015) + (9000 * 0.012) + ((amount - 10000) * 0.009); | |
} | |
const grossRevenue = amount * spotPrice; | |
const netEarnings = grossRevenue - fees; | |
// Update display | |
document.getElementById('gross-revenue').textContent = `$${(grossRevenue).toFixed(2)}`; | |
document.getElementById('total-fees').textContent = `$${fees.toFixed(2)}`; | |
document.getElementById('net-earnings').textContent = `$${netEarnings.toFixed(2)}`; | |
// Calculate break-even (assuming production cost is 70% of spot price for demo) | |
const productionCostPerLb = spotPrice * 0.7; | |
const totalProductionCost = amount * productionCostPerLb; | |
const breakEvenPrice = (totalProductionCost + fees) / amount; | |
const profitMargin = ((netEarnings - totalProductionCost) / totalProductionCost) * 100; | |
document.getElementById('production-cost').textContent = `$${productionCostPerLb.toFixed(2)}/lb`; | |
document.getElementById('break-even-price').textContent = `$${breakEvenPrice.toFixed(2)}/lb`; | |
document.getElementById('profit-margin').textContent = `${profitMargin.toFixed(1)}%`; | |
} | |
// Update supplier calculations when amount changes | |
document.getElementById('supply-amount').addEventListener('input', calculateSupplierEarnings); | |
// Confirm supply agreement | |
document.getElementById('confirm-supply').addEventListener('click', function() { | |
if (!document.getElementById('agree-terms').checked) { | |
alert('Please agree to the terms before confirming.'); | |
return; | |
} | |
const amount = document.getElementById('supply-amount').value; | |
const netEarnings = document.getElementById('net-earnings').textContent; | |
alert(`Supply agreement confirmed for ${amount} lbs of cotton. Estimated net earnings: ${netEarnings}`); | |
supplierWindow.classList.remove('active'); | |
}); | |
// Time period buttons | |
const timeBtns = document.querySelectorAll('.time-btn'); | |
timeBtns.forEach(btn => { | |
btn.addEventListener('click', () => { | |
timeBtns.forEach(b => b.classList.remove('active', 'bg-blue-500', 'text-white')); | |
btn.classList.add('active', 'bg-blue-500', 'text-white'); | |
// Here you would normally fetch new chart data based on the selected period | |
// For demo purposes, we'll just update the chart with random data | |
updateChart(btn.getAttribute('data-period')); | |
}); | |
}); | |
// Initialize chart | |
const ctx = document.getElementById('price-chart').getContext('2d'); | |
let priceChart = new Chart(ctx, { | |
type: 'line', | |
data: { | |
labels: [], | |
datasets: [{ | |
label: 'Cotton Price (USD/lb)', | |
data: [], | |
borderColor: '#3b82f6', | |
backgroundColor: 'rgba(59, 130, 246, 0.1)', | |
borderWidth: 2, | |
fill: true, | |
tension: 0.4 | |
}] | |
}, | |
options: { | |
responsive: true, | |
maintainAspectRatio: false, | |
plugins: { | |
legend: { | |
display: false | |
}, | |
tooltip: { | |
mode: 'index', | |
intersect: false, | |
} | |
}, | |
scales: { | |
y: { | |
beginAtZero: false, | |
grid: { | |
drawBorder: false | |
} | |
}, | |
x: { | |
grid: { | |
display: false | |
} | |
} | |
} | |
} | |
}); | |
// Function to update chart with sample data | |
function updateChart(period) { | |
let labels = []; | |
let data = []; | |
let basePrice = 0.85; | |
// Generate sample data based on period | |
if (period === '1M') { | |
labels = ['Jun 1', 'Jun 5', 'Jun 10', 'Jun 15', 'Jun 20', 'Jun 25', 'Jun 30']; | |
data = [0.82, 0.83, 0.84, 0.86, 0.85, 0.84, 0.85]; | |
} else if (period === '3M') { | |
labels = ['Apr', 'May', 'Jun']; | |
data = [0.78, 0.82, 0.85]; | |
} else if (period === '6M') { | |
labels = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun']; | |
data = [0.75, 0.76, 0.78, 0.80, 0.82, 0.85]; | |
} else if (period === '1Y') { | |
labels = ['Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec', 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun']; | |
data = [0.72, 0.74, 0.73, 0.75, 0.76, 0.77, 0.75, 0.76, 0.78, 0.80, 0.82, 0.85]; | |
} | |
priceChart.data.labels = labels; | |
priceChart.data.datasets[0].data = data; | |
priceChart.update(); | |
} | |
// Initialize with 1M data | |
updateChart('1M'); | |
// Simulate API key (masked) | |
const apiKey = 'ebc6d2b48db541a:im201to74ucouji'.split('').map(() => '*').join(''); | |
console.log('Using API key:', apiKey); | |
// Refresh button functionality | |
document.getElementById('refresh-btn').addEventListener('click', function() { | |
this.innerHTML = '<i class="fas fa-spinner fa-spin mr-2"></i> Refreshing'; | |
this.disabled = true; | |
// Simulate API refresh | |
setTimeout(() => { | |
this.innerHTML = '<i class="fas fa-sync-alt mr-2"></i> Refresh'; | |
this.disabled = false; | |
// Update timestamp | |
const now = new Date(); | |
document.getElementById('update-time').textContent = now.toLocaleTimeString(); | |
// Simulate small price change | |
const currentPriceEl = document.getElementById('current-price'); | |
let price = parseFloat(currentPriceEl.textContent); | |
const change = (Math.random() * 0.02) * (Math.random() > 0.5 ? 1 : -1); | |
price = Math.round((price + change) * 100) / 100; | |
currentPriceEl.textContent = price.toFixed(2); | |
// Update change indicator | |
const changeEl = document.getElementById('price-change'); | |
if (change >= 0) { | |
changeEl.innerHTML = `<i class="fas fa-caret-up mr-1"></i><span>+${change.toFixed(2)} (${(change/price*100).toFixed(1)}%)</span>`; | |
changeEl.className = 'px-3 py-1 rounded-full bg-green-100 text-green-800 flex items-center'; | |
} else { | |
changeEl.innerHTML = `<i class="fas fa-caret-down mr-1"></i><span>${change.toFixed(2)} (${(change/price*100).toFixed(1)}%)</span>`; | |
changeEl.className = 'px-3 py-1 rounded-full bg-red-100 text-red-800 flex items-center'; | |
} | |
// Update supplier window if open | |
if (supplierWindow.classList.contains('active')) { | |
calculateSupplierEarnings(); | |
} | |
}, 1500); | |
}); | |
</script> | |
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=privateuserh/privspot" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> | |
</html> |