| | <!DOCTYPE html> |
| | <html lang="en"> |
| | <head> |
| | <meta charset="UTF-8"> |
| | <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| | <title>Angular Subscription & Data Hub</title> |
| | <script src="https://cdn.tailwindcss.com"></script> |
| | <script src="https://unpkg.com/feather-icons"></script> |
| | <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css"/> |
| | <base href="/"> |
| | <style> |
| | @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&display=swap'); |
| | body { |
| | font-family: 'Poppins', sans-serif; |
| | } |
| | .gradient-bg { |
| | background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); |
| | } |
| | .plan-card:hover { |
| | transform: translateY(-5px); |
| | box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04); |
| | } |
| | .premium-glow { |
| | box-shadow: 0 0 15px rgba(255, 215, 0, 0.6); |
| | } |
| | .print-area { |
| | display: none; |
| | } |
| | @media print { |
| | body * { |
| | visibility: hidden; |
| | } |
| | .print-area, .print-area * { |
| | visibility: visible; |
| | } |
| | .print-area { |
| | position: absolute; |
| | left: 0; |
| | top: 0; |
| | width: 100%; |
| | display: block; |
| | } |
| | .no-print { |
| | display: none !important; |
| | } |
| | } |
| | </style> |
| | </head> |
| | <body class="bg-gray-50 min-h-screen"> |
| | <app-root></app-root> |
| | |
| | |
| | <script> |
| | feather.replace(); |
| | |
| | // This would be in your Angular components in the real implementation |
| | document.addEventListener('DOMContentLoaded', () => { |
| | // Mock Angular-like behavior for this demo |
| | const appRoot = document.querySelector('app-root'); |
| | |
| | // Navigation |
| | appRoot.innerHTML = ` |
| | <div class="flex flex-col min-h-screen"> |
| | |
| | <header class="gradient-bg text-white shadow-lg"> |
| | <div class="container mx-auto px-4 py-6"> |
| | <div class="flex justify-between items-center"> |
| | <h1 class="text-2xl font-bold flex items-center"> |
| | <i data-feather="zap" class="mr-2"></i> |
| | AngularHub |
| | </h1> |
| | <nav class="hidden md:flex space-x-6"> |
| | <button onclick="showModule('plans')" class="px-3 py-2 rounded-lg hover:bg-white hover:bg-opacity-10 transition flex items-center"> |
| | <i data-feather="credit-card" class="mr-2"></i> |
| | Subscription Plans |
| | </button> |
| | <button onclick="showModule('data')" class="px-3 py-2 rounded-lg hover:bg-white hover:bg-opacity-10 transition flex items-center"> |
| | <i data-feather="database" class="mr-2"></i> |
| | API Data Table |
| | </button> |
| | </nav> |
| | <button class="md:hidden" onclick="toggleMobileMenu()"> |
| | <i data-feather="menu"></i> |
| | </button> |
| | </div> |
| | |
| | <div id="mobileMenu" class="hidden md:hidden mt-4 space-y-2"> |
| | <button onclick="showModule('plans')" class="w-full text-left px-3 py-2 rounded-lg hover:bg-white hover:bg-opacity-10 transition flex items-center"> |
| | <i data-feather="credit-card" class="mr-2"></i> |
| | Subscription Plans |
| | </button> |
| | <button onclick="showModule('data')" class="w-full text-left px-3 py-2 rounded-lg hover:bg-white hover:bg-opacity-10 transition flex items-center"> |
| | <i data-feather="database" class="mr-2"></i> |
| | API Data Table |
| | </button> |
| | </div> |
| | </div> |
| | </header> |
| | |
| | |
| | <main class="flex-grow container mx-auto px-4 py-8"> |
| | <div id="plansModule"> |
| | |
| | <h2 class="text-3xl font-bold text-gray-800 mb-8 text-center">Choose Your Plan</h2> |
| | |
| | <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8 mb-12"> |
| | |
| | <div class="plan-card bg-white rounded-xl shadow-md overflow-hidden transition duration-300"> |
| | <div class="p-6"> |
| | <div class="flex justify-between items-start"> |
| | <h3 class="text-xl font-bold text-gray-800">Minimum</h3> |
| | <span class="bg-blue-100 text-blue-800 text-xs px-2 py-1 rounded-full">Basic</span> |
| | </div> |
| | <p class="text-gray-600 text-sm mt-1">Essentials for Startups</p> |
| | </div> |
| | <div class="px-6 pb-4"> |
| | <p class="text-3xl font-bold text-gray-800">100 <span class="text-lg">BDT</span></p> |
| | <p class="text-gray-600 text-sm mt-1">10 Days Unlimited</p> |
| | </div> |
| | <div class="border-t border-gray-100 px-6 py-4"> |
| | <ul class="space-y-2"> |
| | <li class="flex items-center"> |
| | <i data-feather="check" class="text-green-500 mr-2"></i> |
| | <span class="text-gray-600">10 Days Unlimited</span> |
| | </li> |
| | <li class="flex items-center"> |
| | <i data-feather="x" class="text-red-400 mr-2"></i> |
| | <span class="text-gray-600">SMS: OFF</span> |
| | </li> |
| | </ul> |
| | </div> |
| | <div class="px-6 py-4 bg-gray-50"> |
| | <button onclick="selectPlan('minimum')" class="w-full py-2 px-4 bg-blue-600 hover:bg-blue-700 text-white rounded-lg transition"> |
| | Select Plan |
| | </button> |
| | </div> |
| | </div> |
| | |
| | |
| | <div class="plan-card bg-white rounded-xl shadow-md overflow-hidden transition duration-300"> |
| | <div class="p-6"> |
| | <div class="flex justify-between items-start"> |
| | <h3 class="text-xl font-bold text-gray-800">Regular</h3> |
| | <span class="bg-purple-100 text-purple-800 text-xs px-2 py-1 rounded-full">Standard</span> |
| | </div> |
| | <p class="text-gray-600 text-sm mt-1">Balanced and Optimized</p> |
| | </div> |
| | <div class="px-6 pb-4"> |
| | <p class="text-3xl font-bold text-gray-800">300 <span class="text-lg">BDT</span></p> |
| | <p class="text-gray-600 text-sm mt-1">15 Days Unlimited</p> |
| | </div> |
| | <div class="border-t border-gray-100 px-6 py-4"> |
| | <ul class="space-y-2"> |
| | <li class="flex items-center"> |
| | <i data-feather="check" class="text-green-500 mr-2"></i> |
| | <span class="text-gray-600">15 Days Unlimited</span> |
| | </li> |
| | <li class="flex items-center"> |
| | <i data-feather="x" class="text-red-400 mr-2"></i> |
| | <span class="text-gray-600">SMS: OFF</span> |
| | </li> |
| | </ul> |
| | </div> |
| | <div class="px-6 py-4 bg-gray-50"> |
| | <button onclick="selectPlan('regular')" class="w-full py-2 px-4 bg-purple-600 hover:bg-purple-700 text-white rounded-lg transition"> |
| | Select Plan |
| | </button> |
| | </div> |
| | </div> |
| | |
| | |
| | <div class="plan-card bg-white rounded-xl shadow-md overflow-hidden transition duration-300 border-2 border-yellow-400"> |
| | <div class="absolute -top-2 -right-2 bg-yellow-400 text-yellow-800 text-xs font-bold px-2 py-1 rounded-full animate-pulse"> |
| | POPULAR |
| | </div> |
| | <div class="p-6"> |
| | <div class="flex justify-between items-start"> |
| | <h3 class="text-xl font-bold text-gray-800">Popular</h3> |
| | <span class="bg-yellow-100 text-yellow-800 text-xs px-2 py-1 rounded-full">Best Value</span> |
| | </div> |
| | <p class="text-gray-600 text-sm mt-1">The Smart Choice for Success!</p> |
| | </div> |
| | <div class="px-6 pb-4"> |
| | <p class="text-3xl font-bold text-gray-800">500 <span class="text-lg">BDT</span></p> |
| | <p class="text-gray-600 text-sm mt-1">30 Days Unlimited</p> |
| | </div> |
| | <div class="border-t border-gray-100 px-6 py-4"> |
| | <ul class="space-y-2"> |
| | <li class="flex items-center"> |
| | <i data-feather="check" class="text-green-500 mr-2"></i> |
| | <span class="text-gray-600">30 Days Unlimited</span> |
| | </li> |
| | <li class="flex items-center"> |
| | <i data-feather="check" class="text-green-500 mr-2"></i> |
| | <span class="text-gray-600">415 Free SMS</span> |
| | </li> |
| | </ul> |
| | </div> |
| | <div class="px-6 py-4 bg-gray-50"> |
| | <button onclick="selectPlan('popular')" class="w-full py-2 px-4 bg-yellow-500 hover:bg-yellow-600 text-white rounded-lg transition"> |
| | Select Plan |
| | </button> |
| | </div> |
| | </div> |
| | |
| | |
| | <div class="plan-card bg-white rounded-xl shadow-md overflow-hidden transition duration-300"> |
| | <div class="p-6"> |
| | <div class="flex justify-between items-start"> |
| | <h3 class="text-xl font-bold text-gray-800">Enterprise (Monthly)</h3> |
| | <span class="bg-green-100 text-green-800 text-xs px-2 py-1 rounded-full">Premium</span> |
| | </div> |
| | <p class="text-gray-600 text-sm mt-1">Premium Solution</p> |
| | </div> |
| | <div class="px-6 pb-4"> |
| | <p class="text-3xl font-bold text-gray-800">1000 <span class="text-lg">BDT</span></p> |
| | <p class="text-gray-600 text-sm mt-1">30 Days Unlimited</p> |
| | </div> |
| | <div class="border-t border-gray-100 px-6 py-4"> |
| | <ul class="space-y-2"> |
| | <li class="flex items-center"> |
| | <i data-feather="check" class="text-green-500 mr-2"></i> |
| | <span class="text-gray-600">30 Days Unlimited</span> |
| | </li> |
| | <li class="flex items-center"> |
| | <i data-feather="check" class="text-green-500 mr-2"></i> |
| | <span class="text-gray-600">850 Free SMS</span> |
| | </li> |
| | </ul> |
| | </div> |
| | <div class="px-6 py-4 bg-gray-50"> |
| | <button onclick="selectPlan('enterprise-monthly')" class="w-full py-2 px-4 bg-green-600 hover:bg-green-700 text-white rounded-lg transition"> |
| | Select Plan |
| | </button> |
| | </div> |
| | </div> |
| | |
| | |
| | <div class="plan-card bg-white rounded-xl shadow-md overflow-hidden transition duration-300 premium-glow"> |
| | <div class="absolute -top-2 -right-2 bg-gradient-to-r from-purple-500 to-pink-500 text-white text-xs font-bold px-2 py-1 rounded-full"> |
| | PREMIUM |
| | </div> |
| | <div class="p-6"> |
| | <div class="flex justify-between items-start"> |
| | <h3 class="text-xl font-bold text-gray-800">Enterprise (Yearly)</h3> |
| | <span class="bg-pink-100 text-pink-800 text-xs px-2 py-1 rounded-full">Best Offer</span> |
| | </div> |
| | <p class="text-gray-600 text-sm mt-1">Best Value for Long-Term</p> |
| | </div> |
| | <div class="px-6 pb-4"> |
| | <p class="text-3xl font-bold text-gray-800">5000 <span class="text-lg">BDT</span></p> |
| | <p class="text-gray-600 text-sm mt-1">1 Year Unlimited</p> |
| | </div> |
| | <div class="border-t border-gray-100 px-6 py-4"> |
| | <ul class="space-y-2"> |
| | <li class="flex items-center"> |
| | <i data-feather="check" class="text-green-500 mr-2"></i> |
| | <span class="text-gray-600">1 Year Unlimited</span> |
| | </li> |
| | <li class="flex items-center"> |
| | <i data-feather="check" class="text-green-500 mr-2"></i> |
| | <span class="text-gray-600">5000 Free SMS</span> |
| | </li> |
| | </ul> |
| | </div> |
| | <div class="px-6 py-4 bg-gray-50"> |
| | <button onclick="selectPlan('enterprise-yearly')" class="w-full py-2 px-4 bg-gradient-to-r from-purple-500 to-pink-500 hover:from-purple-600 hover:to-pink-600 text-white rounded-lg transition"> |
| | Select Plan |
| | </button> |
| | </div> |
| | </div> |
| | </div> |
| | |
| | |
| | <div id="checkoutSection" class="hidden bg-white rounded-xl shadow-md p-6 max-w-2xl mx-auto"> |
| | <h2 class="text-2xl font-bold text-gray-800 mb-6">Checkout</h2> |
| | |
| | <div class="grid grid-cols-1 md:grid-cols-2 gap-6"> |
| | <div> |
| | <h3 class="text-lg font-semibold text-gray-700 mb-2">Selected Plan</h3> |
| | <div id="selectedPlanInfo" class="bg-gray-50 p-4 rounded-lg"> |
| | |
| | </div> |
| | </div> |
| | |
| | <div> |
| | <h3 class="text-lg font-semibold text-gray-700 mb-2">SMS Options</h3> |
| | <div class="bg-gray-50 p-4 rounded-lg"> |
| | <div class="flex items-center justify-between mb-4"> |
| | <div> |
| | <label class="font-medium text-gray-700">SMS Service</label> |
| | <p class="text-sm text-gray-500">Purchase additional SMS</p> |
| | </div> |
| | <label class="relative inline-flex items-center cursor-pointer"> |
| | <input type="checkbox" id="smsToggle" class="sr-only peer" onchange="toggleSms()"> |
| | <div class="w-11 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-blue-300 rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-blue-600"></div> |
| | </label> |
| | </div> |
| | |
| | <div id="smsOptions" class="hidden"> |
| | <label class="block text-sm font-medium text-gray-700 mb-1">Additional SMS (0.60 BDT per SMS)</label> |
| | <input type="number" id="smsQuantity" min="100" step="100" value="500" class="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500" oninput="calculateTotal()"> |
| | </div> |
| | </div> |
| | </div> |
| | </div> |
| | |
| | <div class="mt-6 bg-blue-50 p-4 rounded-lg"> |
| | <h3 class="text-lg font-semibold text-gray-700 mb-2">Order Summary</h3> |
| | <div class="flex justify-between items-center mb-2"> |
| | <span class="text-gray-600">Plan Price</span> |
| | <span id="planPrice" class="font-medium">0 BDT</span> |
| | </div> |
| | <div id="smsCostContainer" class="hidden flex justify-between items-center mb-2"> |
| | <span class="text-gray-600">Additional SMS Cost</span> |
| | <span id="smsCost" class="font-medium">0 BDT</span> |
| | </div> |
| | <div class="border-t border-gray-200 pt-2 mt-2"> |
| | <div class="flex justify-between items-center"> |
| | <span class="font-semibold">Total</span> |
| | <span id="totalPrice" class="font-bold text-lg">0 BDT</span> |
| | </div> |
| | </div> |
| | </div> |
| | |
| | <div class="mt-6 flex justify-end space-x-3"> |
| | <button onclick="cancelCheckout()" class="px-4 py-2 border border-gray-300 rounded-md text-gray-700 hover:bg-gray-50 transition"> |
| | Cancel |
| | </button> |
| | <button onclick="processPayment()" class="px-6 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition flex items-center"> |
| | <i data-feather="credit-card" class="mr-2"></i> |
| | Buy Now |
| | </button> |
| | </div> |
| | </div> |
| | </div> |
| | |
| | <div id="dataModule" class="hidden"> |
| | |
| | <div class="flex justify-between items-center mb-6"> |
| | <h2 class="text-3xl font-bold text-gray-800">User Data from API</h2> |
| | <button onclick="printTable()" class="px-4 py-2 bg-green-600 text-white rounded-md hover:bg-green-700 transition flex items-center"> |
| | <i data-feather="printer" class="mr-2"></i> |
| | Print Table |
| | </button> |
| | </div> |
| | |
| | <div class="bg-white rounded-lg shadow-md overflow-hidden"> |
| | <div class="p-4 border-b border-gray-200 flex justify-between items-center"> |
| | <div class="flex items-center"> |
| | <input type="text" id="searchInput" placeholder="Search..." class="px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"> |
| | <button onclick="filterTable()" class="ml-2 px-3 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition"> |
| | <i data-feather="search"></i> |
| | </button> |
| | </div> |
| | <div class="flex items-center"> |
| | <span class="text-sm text-gray-600 mr-2">Sort by:</span> |
| | <select id="sortSelect" onchange="sortTable()" class="px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"> |
| | <option value="name">Name</option> |
| | <option value="email">Email</option> |
| | <option value="city">City</option> |
| | </select> |
| | </div> |
| | </div> |
| | |
| | <div class="print-area"> |
| | <table id="dataTable" class="min-w-full divide-y divide-gray-200"> |
| | <thead class="bg-gray-50"> |
| | <tr> |
| | <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">ID</th> |
| | <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Name</th> |
| | <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Email</th> |
| | <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">City</th> |
| | <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Company</th> |
| | </tr> |
| | </thead> |
| | <tbody id="tableBody" class="bg-white divide-y divide-gray-200"> |
| | |
| | </tbody> |
| | </table> |
| | </div> |
| | |
| | <div class="p-4 border-t border-gray-200 flex justify-between items-center"> |
| | <div class="text-sm text-gray-600"> |
| | Showing <span id="startRow">1</span> to <span id="endRow">10</span> of <span id="totalRows">50</span> entries |
| | </div> |
| | <div class="flex space-x-2"> |
| | <button onclick="prevPage()" class="px-3 py-1 border border-gray-300 rounded-md hover:bg-gray-50 transition"> |
| | <i data-feather="chevron-left"></i> |
| | </button> |
| | <button onclick="nextPage()" class="px-3 py-1 border border-gray-300 rounded-md hover:bg-gray-50 transition"> |
| | <i data-feather="chevron-right"></i> |
| | </button> |
| | </div> |
| | </div> |
| | </div> |
| | </div> |
| | </main> |
| | |
| | |
| | <footer class="gradient-bg text-white py-8"> |
| | <div class="container mx-auto px-4"> |
| | <div class="flex flex-col md:flex-row justify-between items-center"> |
| | <div class="mb-4 md:mb-0"> |
| | <h2 class="text-xl font-bold flex items-center"> |
| | <i data-feather="zap" class="mr-2"></i> |
| | AngularHub |
| | </h2> |
| | <p class="text-sm mt-1">Subscription & Data Management Solution</p> |
| | </div> |
| | <div class="flex space-x-4"> |
| | <a href="#" class="hover:text-blue-200 transition"> |
| | <i data-feather="github"></i> |
| | </a> |
| | <a href="#" class="hover:text-blue-200 transition"> |
| | <i data-feather="twitter"></i> |
| | </a> |
| | <a href="#" class="hover:text-blue-200 transition"> |
| | <i data-feather="linkedin"></i> |
| | </a> |
| | </div> |
| | </div> |
| | <div class="border-t border-blue-400 mt-6 pt-6 text-center text-sm"> |
| | <p>© 2023 AngularHub. All rights reserved.</p> |
| | </div> |
| | </div> |
| | </footer> |
| | </div> |
| | `; |
| | |
| | // Initialize Feather Icons |
| | feather.replace(); |
| | |
| | // Show plans module by default |
| | showModule('plans'); |
| | |
| | // Load sample data for the table (in a real Angular app, this would be an API call) |
| | loadSampleData(); |
| | }); |
| | |
| | // Mock functions that would be in Angular components/services |
| | function showModule(moduleName) { |
| | document.getElementById('plansModule').classList.add('hidden'); |
| | document.getElementById('dataModule').classList.add('hidden'); |
| | |
| | if (moduleName === 'plans') { |
| | document.getElementById('plansModule').classList.remove('hidden'); |
| | } else { |
| | document.getElementById('dataModule').classList.remove('hidden'); |
| | } |
| | |
| | // Close mobile menu if open |
| | document.getElementById('mobileMenu').classList.add('hidden'); |
| | } |
| | |
| | function toggleMobileMenu() { |
| | const menu = document.getElementById('mobileMenu'); |
| | if (menu.classList.contains('hidden')) { |
| | menu.classList.remove('hidden'); |
| | } else { |
| | menu.classList.add('hidden'); |
| | } |
| | } |
| | |
| | // Subscription Plans Module Functions |
| | const plans = { |
| | 'minimum': { |
| | name: 'Minimum', |
| | price: 100, |
| | duration: '10 Days Unlimited', |
| | sms: 'OFF', |
| | tagline: 'Essentials for Startups - Simple, Affordable, and Effective.' |
| | }, |
| | 'regular': { |
| | name: 'Regular', |
| | price: 300, |
| | duration: '15 Days Unlimited', |
| | sms: 'OFF', |
| | tagline: 'Balanced and Optimized - Perfect for Growing Businesses.' |
| | }, |
| | 'popular': { |
| | name: 'Popular', |
| | price: 500, |
| | duration: '30 Days Unlimited', |
| | sms: '415 Free SMS', |
| | tagline: 'The Smart Choice for Success! Our Most Popular Plan.' |
| | }, |
| | 'enterprise-monthly': { |
| | name: 'Enterprise (Monthly)', |
| | price: 1000, |
| | duration: '30 Days Unlimited', |
| | sms: '850 Free SMS', |
| | tagline: 'Premium Solution for Enterprises.' |
| | }, |
| | 'enterprise-yearly': { |
| | name: 'Enterprise (Yearly)', |
| | price: 5000, |
| | duration: '1 Year Unlimited', |
| | sms: '5000 Free SMS', |
| | tagline: 'Best Value for Long-Term Growth.' |
| | } |
| | }; |
| | |
| | let selectedPlan = null; |
| | let smsEnabled = false; |
| | let smsQuantity = 500; |
| | |
| | function selectPlan(planId) { |
| | selectedPlan = plans[planId]; |
| | |
| | // Update selected plan info |
| | const planInfoDiv = document.getElementById('selectedPlanInfo'); |
| | planInfoDiv.innerHTML = ` |
| | <h4 class="font-bold text-lg">${selectedPlan.name}</h4> |
| | <p class="text-gray-600">${selectedPlan.tagline}</p> |
| | <div class="mt-2 flex justify-between"> |
| | <span class="text-gray-700">Price:</span> |
| | <span class="font-medium">${selectedPlan.price} BDT</span> |
| | </div> |
| | <div class="flex justify-between"> |
| | <span class="text-gray-700">Duration:</span> |
| | <span class="font-medium">${selectedPlan.duration}</span> |
| | </div> |
| | <div class="flex justify-between"> |
| | <span class="text-gray-700">SMS:</span> |
| | <span class="font-medium">${selectedPlan.sms}</span> |
| | </div> |
| | `; |
| | |
| | // Show checkout section |
| | document.getElementById('checkoutSection').classList.remove('hidden'); |
| | |
| | // Update prices |
| | calculateTotal(); |
| | |
| | // Scroll to checkout |
| | document.getElementById('checkoutSection').scrollIntoView({ behavior: 'smooth' }); |
| | } |
| | |
| | function toggleSms() { |
| | smsEnabled = !smsEnabled; |
| | const smsOptions = document.getElementById('smsOptions'); |
| | const smsCostContainer = document.getElementById('smsCostContainer'); |
| | |
| | if (smsEnabled) { |
| | smsOptions.classList.remove('hidden'); |
| | smsCostContainer.classList.remove('hidden'); |
| | } else { |
| | smsOptions.classList.add('hidden'); |
| | smsCostContainer.classList.add('hidden'); |
| | } |
| | |
| | calculateTotal(); |
| | } |
| | |
| | function calculateTotal() { |
| | if (!selectedPlan) return; |
| | |
| | const planPrice = selectedPlan.price; |
| | let total = planPrice; |
| | |
| | document.getElementById('planPrice').textContent = `${planPrice} BDT`; |
| | |
| | if (smsEnabled) { |
| | smsQuantity = parseInt(document.getElementById('smsQuantity').value) || 500; |
| | const smsCost = Math.floor(smsQuantity * 0.6); |
| | document.getElementById('smsCost').textContent = `${smsCost} BDT`; |
| | total += smsCost; |
| | } |
| | |
| | document.getElementById('totalPrice').textContent = `${total} BDT`; |
| | } |
| | |
| | function cancelCheckout() { |
| | document.getElementById('checkoutSection').classList.add('hidden'); |
| | selectedPlan = null; |
| | } |
| | |
| | function processPayment() { |
| | alert('Payment processing would happen here in a real application!'); |
| | // Reset after "payment" |
| | document.getElementById('checkoutSection').classList.add('hidden'); |
| | selectedPlan = null; |
| | } |
| | |
| | // Data Table Module Functions |
| | let currentPage = 1; |
| | const rowsPerPage = 10; |
| | let allData = []; |
| | let filteredData = []; |
| | let sortField = 'name'; |
| | let sortDirection = 'asc'; |
| | |
| | function loadSampleData() { |
| | // In a real Angular app, this would be an HTTP GET request to the API |
| | // Mock data for demonstration |
| | allData = [ |
| | { id: 1, name: 'Leanne Graham', email: 'leanne@example.com', city: 'Gwenborough', company: 'Romaguera-Crona' }, |
| | { id: 2, name: 'Ervin Howell', email: 'ervin@example.com', city: 'Wisokyburgh', company: 'Deckow-Crist' }, |
| | { id: 3, name: 'Clementine Bauch', email: 'clementine@example.com', city: 'McKenziehaven', company: 'Romaguera-Jacobson' }, |
| | { id: 4, name: 'Patricia Lebsack', email: 'patricia@example.com', city: 'South Elvis', company: 'Robel-Corkery' }, |
| | { id: 5, name: 'Chelsey Dietrich', email: 'chelsey@example.com', city: 'Roscoeview', company: 'Keebler LLC' }, |
| | { id: 6, name: 'Mrs. Dennis Schulist', email: 'dennis@example.com', city: 'South Christy', company: 'Considine-Lockman' }, |
| | { id: 7, name: 'Kurtis Weissnat', email: 'kurtis@example.com', city: 'Howemouth', company: 'Johns Group' }, |
| | { id: 8, name: 'Nicholas Runolfsdottir V', email: 'nicholas@example.com', city: 'Aliyaview', company: 'Abernathy Group' }, |
| | { id: 9, name: 'Glenna Reichert', email: 'glenna@example.com', city: 'Bartholomebury', company: 'Yost and Sons' }, |
| | { id: 10, name: 'Clementina DuBuque', email: 'clementina@example.com', city: 'Lebsackbury', company: 'Hoeger LLC' }, |
| | { id: 11, name: 'John Doe', email: 'john@example.com', city: 'New York', company: 'ABC Corp' }, |
| | { id: 12, name: 'Jane Smith', email: 'jane@example.com', city: 'Los Angeles', company: 'XYZ Inc' } |
| | ]; |
| | |
| | filteredData = [...allData]; |
| | renderTable(); |
| | } |
| | |
| | function renderTable() { |
| | const tableBody = document.getElementById('tableBody'); |
| | tableBody.innerHTML = ''; |
| | |
| | // Sort data |
| | filteredData.sort((a, b) => { |
| | if (a[sortField] < b[sortField]) return sortDirection === 'asc' ? -1 : 1; |
| | if (a[sortField] > b[sortField]) return sortDirection === 'asc' ? 1 : -1; |
| | return 0; |
| | }); |
| | |
| | // Pagination |
| | const startIdx = (currentPage - 1) * rowsPerPage; |
| | const endIdx = Math.min(startIdx + rowsPerPage, filteredData.length); |
| | const pageData = filteredData.slice(startIdx, endIdx); |
| | |
| | // Update pagination info |
| | document.getElementById('startRow').textContent = startIdx + 1; |
| | document.getElementById('endRow').textContent = endIdx; |
| | document.getElementById('totalRows').textContent = filteredData.length; |
| | |
| | // Render rows |
| | pageData.forEach(item => { |
| | const row = document.createElement('tr'); |
| | row.innerHTML = ` |
| | <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">${item.id}</td> |
| | <td class="px-6 py-4 whitespace-nowrap"> |
| | <div class="text-sm font-medium text-gray-900">${item.name}</div> |
| | </td> |
| | <td class="px-6 py-4 whitespace-nowrap"> |
| | <div class="text-sm text-gray-900">${item.email}</div> |
| | </td> |
| | <td class="px-6 py-4 whitespace-nowrap"> |
| | <div class="text-sm text-gray-900">${item.city}</div> |
| | </td> |
| | <td class="px-6 py-4 whitespace-nowrap"> |
| | <div class="text-sm text-gray-900">${item.company}</div> |
| | </td> |
| | `; |
| | tableBody.appendChild(row); |
| | }); |
| | |
| | feather.replace(); |
| | } |
| | |
| | function filterTable() { |
| | const searchTerm = document.getElementById('searchInput').value.toLowerCase(); |
| | |
| | if (!searchTerm) { |
| | filteredData = [...allData]; |
| | } else { |
| | filteredData = allData.filter(item => |
| | item.name.toLowerCase().includes(searchTerm) || |
| | item.email.toLowerCase().includes(searchTerm) || |
| | item.city.toLowerCase().includes(searchTerm) || |
| | item.company.toLowerCase().includes(searchTerm) |
| | ); |
| | } |
| | |
| | currentPage = 1; |
| | renderTable(); |
| | } |
| | |
| | function sortTable() { |
| | const sortSelect = document.getElementById('sortSelect'); |
| | sortField = sortSelect.value; |
| | sortDirection = sortDirection === 'asc' ? 'desc' : 'asc'; |
| | renderTable(); |
| | } |
| | |
| | function prevPage() { |
| | if (currentPage > 1) { |
| | currentPage--; |
| | renderTable(); |
| | } |
| | } |
| | |
| | function nextPage() { |
| | const totalPages = Math.ceil(filteredData.length / rowsPerPage); |
| | if (currentPage < totalPages) { |
| | currentPage++; |
| | renderTable(); |
| | } |
| | } |
| | |
| | function printTable() { |
| | window.print(); |
| | } |
| | </script> |
| | </body> |
| | </html> |
| |
|