Sadik386's picture
you are required to complete a pure Angular project assignment. This task focuses entirely on Angular development, component architecture, API integration, and frontend functionality.
64bbb5e verified
<!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>
<!-- Angular scripts will be loaded here in actual project -->
<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 -->
<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>
<!-- Mobile menu -->
<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 Content -->
<main class="flex-grow container mx-auto px-4 py-8">
<div id="plansModule">
<!-- Subscription Plans Module -->
<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">
<!-- Minimum Plan -->
<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>
<!-- Regular Plan -->
<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>
<!-- Popular Plan -->
<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>
<!-- Enterprise Monthly -->
<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>
<!-- Enterprise Yearly -->
<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>
<!-- Checkout Section (hidden by default) -->
<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">
<!-- Plan info will be inserted here -->
</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">
<!-- API Data Table Module -->
<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">
<!-- Data will be loaded here -->
</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 -->
<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>