Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Bank Account System</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> | |
| .account-card { | |
| transition: all 0.3s ease; | |
| box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); | |
| } | |
| .account-card:hover { | |
| transform: translateY(-5px); | |
| box-shadow: 0 10px 15px rgba(0, 0, 0, 0.1); | |
| } | |
| .transaction-history { | |
| max-height: 300px; | |
| overflow-y: auto; | |
| } | |
| .transaction-item { | |
| border-left: 3px solid; | |
| transition: all 0.2s ease; | |
| } | |
| .transaction-item:hover { | |
| background-color: rgba(0, 0, 0, 0.02); | |
| } | |
| .deposit { | |
| border-left-color: #10b981; | |
| } | |
| .withdrawal { | |
| border-left-color: #ef4444; | |
| } | |
| .interest { | |
| border-left-color: #3b82f6; | |
| } | |
| /* Custom scrollbar */ | |
| .transaction-history::-webkit-scrollbar { | |
| width: 6px; | |
| } | |
| .transaction-history::-webkit-scrollbar-track { | |
| background: #f1f1f1; | |
| } | |
| .transaction-history::-webkit-scrollbar-thumb { | |
| background: #888; | |
| border-radius: 3px; | |
| } | |
| .transaction-history::-webkit-scrollbar-thumb:hover { | |
| background: #555; | |
| } | |
| </style> | |
| </head> | |
| <body class="bg-gray-50 min-h-screen"> | |
| <div class="container mx-auto px-4 py-8"> | |
| <header class="text-center mb-12"> | |
| <h1 class="text-4xl font-bold text-indigo-700 mb-2">Bank Account System</h1> | |
| <p class="text-gray-600">Manage your accounts with ease</p> | |
| </header> | |
| <div class="grid grid-cols-1 md:grid-cols-2 gap-8"> | |
| <!-- Regular Account Card --> | |
| <div class="account-card bg-white rounded-lg p-6"> | |
| <div class="flex items-center justify-between mb-4"> | |
| <h2 class="text-2xl font-semibold text-gray-800">Regular Account</h2> | |
| <span class="bg-indigo-100 text-indigo-800 px-3 py-1 rounded-full text-sm font-medium"> | |
| <i class="fas fa-wallet mr-1"></i> Standard | |
| </span> | |
| </div> | |
| <div class="mb-6"> | |
| <div class="flex justify-between items-center mb-2"> | |
| <span class="text-gray-600">Account Number:</span> | |
| <span id="accountNumber" class="font-mono font-medium">Not set</span> | |
| </div> | |
| <div class="flex justify-between items-center"> | |
| <span class="text-gray-600">Balance:</span> | |
| <span id="accountBalance" class="text-2xl font-bold">$0.00</span> | |
| </div> | |
| </div> | |
| <div class="space-y-4 mb-6"> | |
| <div class="flex space-x-2"> | |
| <input type="number" id="accountDepositAmount" placeholder="Amount" class="flex-1 px-4 py-2 border rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500"> | |
| <button onclick="depositToAccount()" class="bg-green-600 hover:bg-green-700 text-white px-4 py-2 rounded-lg transition flex items-center"> | |
| <i class="fas fa-plus-circle mr-2"></i> Deposit | |
| </button> | |
| </div> | |
| <div class="flex space-x-2"> | |
| <input type="number" id="accountWithdrawAmount" placeholder="Amount" class="flex-1 px-4 py-2 border rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500"> | |
| <button onclick="withdrawFromAccount()" class="bg-red-600 hover:bg-red-700 text-white px-4 py-2 rounded-lg transition flex items-center"> | |
| <i class="fas fa-minus-circle mr-2"></i> Withdraw | |
| </button> | |
| </div> | |
| </div> | |
| <div class="bg-gray-100 p-4 rounded-lg"> | |
| <h3 class="font-medium text-gray-700 mb-2">Transaction History</h3> | |
| <div id="accountTransactions" class="transaction-history space-y-2"> | |
| <p class="text-gray-500 text-sm">No transactions yet</p> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Savings Account Card --> | |
| <div class="account-card bg-white rounded-lg p-6"> | |
| <div class="flex items-center justify-between mb-4"> | |
| <h2 class="text-2xl font-semibold text-gray-800">Savings Account</h2> | |
| <span class="bg-green-100 text-green-800 px-3 py-1 rounded-full text-sm font-medium"> | |
| <i class="fas fa-piggy-bank mr-1"></i> Savings | |
| </span> | |
| </div> | |
| <div class="mb-6"> | |
| <div class="flex justify-between items-center mb-2"> | |
| <span class="text-gray-600">Account Number:</span> | |
| <span id="savingsAccountNumber" class="font-mono font-medium">Not set</span> | |
| </div> | |
| <div class="flex justify-between items-center mb-1"> | |
| <span class="text-gray-600">Balance:</span> | |
| <span id="savingsAccountBalance" class="text-2xl font-bold">$0.00</span> | |
| </div> | |
| <div class="flex justify-between items-center"> | |
| <span class="text-gray-600">Interest Rate:</span> | |
| <span id="savingsInterestRate" class="font-medium">0%</span> | |
| </div> | |
| </div> | |
| <div class="space-y-4 mb-6"> | |
| <div class="flex space-x-2"> | |
| <input type="number" id="savingsDepositAmount" placeholder="Amount" class="flex-1 px-4 py-2 border rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500"> | |
| <button onclick="depositToSavings()" class="bg-green-600 hover:bg-green-700 text-white px-4 py-2 rounded-lg transition flex items-center"> | |
| <i class="fas fa-plus-circle mr-2"></i> Deposit | |
| </button> | |
| </div> | |
| <div class="flex space-x-2"> | |
| <input type="number" id="savingsWithdrawAmount" placeholder="Amount" class="flex-1 px-4 py-2 border rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500"> | |
| <button onclick="withdrawFromSavings()" class="bg-red-600 hover:bg-red-700 text-white px-4 py-2 rounded-lg transition flex items-center"> | |
| <i class="fas fa-minus-circle mr-2"></i> Withdraw | |
| </button> | |
| </div> | |
| <div class="flex space-x-2"> | |
| <input type="number" id="interestRateInput" placeholder="Set interest rate (%)" class="flex-1 px-4 py-2 border rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500"> | |
| <button onclick="setInterestRate()" class="bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded-lg transition flex items-center"> | |
| <i class="fas fa-percent mr-2"></i> Set Rate | |
| </button> | |
| </div> | |
| <button onclick="applyInterest()" class="w-full bg-purple-600 hover:bg-purple-700 text-white px-4 py-2 rounded-lg transition flex items-center justify-center"> | |
| <i class="fas fa-coins mr-2"></i> Apply Interest | |
| </button> | |
| </div> | |
| <div class="bg-gray-100 p-4 rounded-lg"> | |
| <h3 class="font-medium text-gray-700 mb-2">Transaction History</h3> | |
| <div id="savingsTransactions" class="transaction-history space-y-2"> | |
| <p class="text-gray-500 text-sm">No transactions yet</p> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Account Creation Section --> | |
| <div class="mt-12 bg-white rounded-lg p-6 shadow-md max-w-2xl mx-auto"> | |
| <h2 class="text-xl font-semibold text-gray-800 mb-4">Create New Accounts</h2> | |
| <div class="grid grid-cols-1 md:grid-cols-2 gap-6"> | |
| <div> | |
| <h3 class="font-medium text-gray-700 mb-2">Regular Account</h3> | |
| <div class="flex space-x-2"> | |
| <input type="number" id="newAccountNumber" placeholder="Account number" class="flex-1 px-4 py-2 border rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500"> | |
| <button onclick="createAccount()" class="bg-indigo-600 hover:bg-indigo-700 text-white px-4 py-2 rounded-lg transition"> | |
| Create | |
| </button> | |
| </div> | |
| </div> | |
| <div> | |
| <h3 class="font-medium text-gray-700 mb-2">Savings Account</h3> | |
| <div class="flex space-x-2"> | |
| <input type="number" id="newSavingsAccountNumber" placeholder="Account number" class="flex-1 px-4 py-2 border rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500"> | |
| <button onclick="createSavingsAccount()" class="bg-green-600 hover:bg-green-700 text-white px-4 py-2 rounded-lg transition"> | |
| Create | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <script> | |
| // Base Account class | |
| class Account { | |
| constructor(accountNumber, initialBalance = 0) { | |
| this.accountNumber = accountNumber; | |
| this.balance = initialBalance; | |
| this.transactions = []; | |
| } | |
| deposit(amount) { | |
| if (amount > 0) { | |
| this.balance += amount; | |
| this.transactions.push({ | |
| type: 'deposit', | |
| amount: amount, | |
| timestamp: new Date() | |
| }); | |
| return true; | |
| } | |
| return false; | |
| } | |
| withdraw(amount) { | |
| if (amount > 0 && amount <= this.balance) { | |
| this.balance -= amount; | |
| this.transactions.push({ | |
| type: 'withdrawal', | |
| amount: amount, | |
| timestamp: new Date() | |
| }); | |
| return true; | |
| } | |
| return false; | |
| } | |
| getAccountInfo() { | |
| return { | |
| accountNumber: this.accountNumber, | |
| balance: this.balance, | |
| transactions: this.transactions | |
| }; | |
| } | |
| } | |
| // SavingsAccount class that inherits from Account | |
| class SavingsAccount extends Account { | |
| constructor(accountNumber, initialBalance = 0, interestRate = 0) { | |
| super(accountNumber, initialBalance); | |
| this.interestRate = interestRate; | |
| } | |
| setInterestRate(rate) { | |
| if (rate >= 0) { | |
| this.interestRate = rate; | |
| return true; | |
| } | |
| return false; | |
| } | |
| applyInterest() { | |
| const interest = this.balance * (this.interestRate / 100); | |
| this.balance += interest; | |
| this.transactions.push({ | |
| type: 'interest', | |
| amount: interest, | |
| timestamp: new Date() | |
| }); | |
| return interest; | |
| } | |
| getAccountInfo() { | |
| return { | |
| ...super.getAccountInfo(), | |
| interestRate: this.interestRate | |
| }; | |
| } | |
| } | |
| // Create instances of the classes | |
| let regularAccount = null; | |
| let savingsAccount = null; | |
| // Helper function to format currency | |
| function formatCurrency(amount) { | |
| return new Intl.NumberFormat('en-US', { | |
| style: 'currency', | |
| currency: 'USD' | |
| }).format(amount); | |
| } | |
| // Helper function to format date | |
| function formatDate(date) { | |
| return new Intl.DateTimeFormat('en-US', { | |
| year: 'numeric', | |
| month: 'short', | |
| day: 'numeric', | |
| hour: '2-digit', | |
| minute: '2-digit', | |
| second: '2-digit' | |
| }).format(date); | |
| } | |
| // Update UI functions | |
| function updateAccountUI() { | |
| if (regularAccount) { | |
| document.getElementById('accountNumber').textContent = regularAccount.accountNumber; | |
| document.getElementById('accountBalance').textContent = formatCurrency(regularAccount.balance); | |
| const transactionsContainer = document.getElementById('accountTransactions'); | |
| if (regularAccount.transactions.length > 0) { | |
| transactionsContainer.innerHTML = regularAccount.transactions.map(t => ` | |
| <div class="transaction-item ${t.type} p-2 bg-white rounded"> | |
| <div class="flex justify-between"> | |
| <span class="font-medium capitalize">${t.type}</span> | |
| <span class="${t.type === 'deposit' ? 'text-green-600' : 'text-red-600'} font-medium">${t.type === 'deposit' ? '+' : '-'}${formatCurrency(t.amount)}</span> | |
| </div> | |
| <div class="text-xs text-gray-500">${formatDate(t.timestamp)}</div> | |
| </div> | |
| `).join(''); | |
| } else { | |
| transactionsContainer.innerHTML = '<p class="text-gray-500 text-sm">No transactions yet</p>'; | |
| } | |
| } | |
| } | |
| function updateSavingsAccountUI() { | |
| if (savingsAccount) { | |
| document.getElementById('savingsAccountNumber').textContent = savingsAccount.accountNumber; | |
| document.getElementById('savingsAccountBalance').textContent = formatCurrency(savingsAccount.balance); | |
| document.getElementById('savingsInterestRate').textContent = `${savingsAccount.interestRate}%`; | |
| const transactionsContainer = document.getElementById('savingsTransactions'); | |
| if (savingsAccount.transactions.length > 0) { | |
| transactionsContainer.innerHTML = savingsAccount.transactions.map(t => ` | |
| <div class="transaction-item ${t.type} p-2 bg-white rounded"> | |
| <div class="flex justify-between"> | |
| <span class="font-medium capitalize">${t.type}</span> | |
| <span class="${t.type === 'deposit' || t.type === 'interest' ? 'text-green-600' : 'text-red-600'} font-medium">${t.type === 'withdrawal' ? '-' : '+'}${formatCurrency(t.amount)}</span> | |
| </div> | |
| <div class="text-xs text-gray-500">${formatDate(t.timestamp)}</div> | |
| </div> | |
| `).join(''); | |
| } else { | |
| transactionsContainer.innerHTML = '<p class="text-gray-500 text-sm">No transactions yet</p>'; | |
| } | |
| } | |
| } | |
| // Account creation functions | |
| function createAccount() { | |
| const accountNumber = document.getElementById('newAccountNumber').value; | |
| if (accountNumber) { | |
| regularAccount = new Account(accountNumber); | |
| updateAccountUI(); | |
| document.getElementById('newAccountNumber').value = ''; | |
| showToast('Regular account created successfully!', 'success'); | |
| } else { | |
| showToast('Please enter an account number', 'error'); | |
| } | |
| } | |
| function createSavingsAccount() { | |
| const accountNumber = document.getElementById('newSavingsAccountNumber').value; | |
| if (accountNumber) { | |
| savingsAccount = new SavingsAccount(accountNumber); | |
| updateSavingsAccountUI(); | |
| document.getElementById('newSavingsAccountNumber').value = ''; | |
| showToast('Savings account created successfully!', 'success'); | |
| } else { | |
| showToast('Please enter an account number', 'error'); | |
| } | |
| } | |
| // Transaction functions for regular account | |
| function depositToAccount() { | |
| if (!regularAccount) { | |
| showToast('Please create a regular account first', 'error'); | |
| return; | |
| } | |
| const amount = parseFloat(document.getElementById('accountDepositAmount').value); | |
| if (isNaN(amount) || amount <= 0) { | |
| showToast('Please enter a valid amount', 'error'); | |
| return; | |
| } | |
| if (regularAccount.deposit(amount)) { | |
| updateAccountUI(); | |
| document.getElementById('accountDepositAmount').value = ''; | |
| showToast(`Deposit of ${formatCurrency(amount)} successful`, 'success'); | |
| } else { | |
| showToast('Deposit failed', 'error'); | |
| } | |
| } | |
| function withdrawFromAccount() { | |
| if (!regularAccount) { | |
| showToast('Please create a regular account first', 'error'); | |
| return; | |
| } | |
| const amount = parseFloat(document.getElementById('accountWithdrawAmount').value); | |
| if (isNaN(amount) || amount <= 0) { | |
| showToast('Please enter a valid amount', 'error'); | |
| return; | |
| } | |
| if (regularAccount.withdraw(amount)) { | |
| updateAccountUI(); | |
| document.getElementById('accountWithdrawAmount').value = ''; | |
| showToast(`Withdrawal of ${formatCurrency(amount)} successful`, 'success'); | |
| } else { | |
| showToast('Withdrawal failed - insufficient funds or invalid amount', 'error'); | |
| } | |
| } | |
| // Transaction functions for savings account | |
| function depositToSavings() { | |
| if (!savingsAccount) { | |
| showToast('Please create a savings account first', 'error'); | |
| return; | |
| } | |
| const amount = parseFloat(document.getElementById('savingsDepositAmount').value); | |
| if (isNaN(amount) || amount <= 0) { | |
| showToast('Please enter a valid amount', 'error'); | |
| return; | |
| } | |
| if (savingsAccount.deposit(amount)) { | |
| updateSavingsAccountUI(); | |
| document.getElementById('savingsDepositAmount').value = ''; | |
| showToast(`Deposit of ${formatCurrency(amount)} successful`, 'success'); | |
| } else { | |
| showToast('Deposit failed', 'error'); | |
| } | |
| } | |
| function withdrawFromSavings() { | |
| if (!savingsAccount) { | |
| showToast('Please create a savings account first', 'error'); | |
| return; | |
| } | |
| const amount = parseFloat(document.getElementById('savingsWithdrawAmount').value); | |
| if (isNaN(amount) || amount <= 0) { | |
| showToast('Please enter a valid amount', 'error'); | |
| return; | |
| } | |
| if (savingsAccount.withdraw(amount)) { | |
| updateSavingsAccountUI(); | |
| document.getElementById('savingsWithdrawAmount').value = ''; | |
| showToast(`Withdrawal of ${formatCurrency(amount)} successful`, 'success'); | |
| } else { | |
| showToast('Withdrawal failed - insufficient funds or invalid amount', 'error'); | |
| } | |
| } | |
| function setInterestRate() { | |
| if (!savingsAccount) { | |
| showToast('Please create a savings account first', 'error'); | |
| return; | |
| } | |
| const rate = parseFloat(document.getElementById('interestRateInput').value); | |
| if (isNaN(rate) || rate < 0) { | |
| showToast('Please enter a valid interest rate', 'error'); | |
| return; | |
| } | |
| if (savingsAccount.setInterestRate(rate)) { | |
| updateSavingsAccountUI(); | |
| document.getElementById('interestRateInput').value = ''; | |
| showToast(`Interest rate set to ${rate}%`, 'success'); | |
| } else { | |
| showToast('Failed to set interest rate', 'error'); | |
| } | |
| } | |
| function applyInterest() { | |
| if (!savingsAccount) { | |
| showToast('Please create a savings account first', 'error'); | |
| return; | |
| } | |
| if (savingsAccount.interestRate <= 0) { | |
| showToast('Please set a positive interest rate first', 'error'); | |
| return; | |
| } | |
| const interest = savingsAccount.applyInterest(); | |
| updateSavingsAccountUI(); | |
| showToast(`Interest of ${formatCurrency(interest)} applied to account`, 'success'); | |
| } | |
| // Toast notification function | |
| function showToast(message, type = 'info') { | |
| const toast = document.createElement('div'); | |
| toast.className = `fixed bottom-4 right-4 px-6 py-3 rounded-lg shadow-lg text-white font-medium flex items-center ${ | |
| type === 'success' ? 'bg-green-500' : | |
| type === 'error' ? 'bg-red-500' : 'bg-blue-500' | |
| }`; | |
| const icon = type === 'success' ? 'fa-check-circle' : | |
| type === 'error' ? 'fa-exclamation-circle' : 'fa-info-circle'; | |
| toast.innerHTML = ` | |
| <i class="fas ${icon} mr-2"></i> | |
| <span>${message}</span> | |
| `; | |
| document.body.appendChild(toast); | |
| setTimeout(() => { | |
| toast.classList.add('opacity-0', 'transition-opacity', 'duration-300'); | |
| setTimeout(() => toast.remove(), 300); | |
| }, 3000); | |
| } | |
| </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=davinchi111/my" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> | |
| </html> |