BuggyWeb
18 hours ago in HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Corporate Dashboard</title>
<script src="https://cdn.tailwindcss.com"></script>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;700&display=swap" rel="stylesheet">
<style>
/* Custom styles can go here */
body {
font-family: 'Inter', sans-serif;
}
/* Style for the important button */
.btn-important {
background-color: #ef4444; /* red-500 */
color: white;
}
/* Overriding style to demonstrate specificity issue */
div .btn {
background-color: #3b82f6; /* blue-500 */
}
</style>
</head>
<body class="bg-gray-100 text-gray-800">
<div class="container mx-auto p-4 md:p-8">
<header class="mb-8">
<h1 class="text-3xl font-bold text-gray-900">Company Dashboard</h1>
<p class="text-gray-600">Overview of key metrics and data.</p>
</header>
<main class="grid grid-cols-1 md:grid-cols-3 gap-8">
<!-- Card 1: User Loader -->
<div class="md:col-span-2 bg-white p-6 rounded-lg shadow-md">
<h2 class="text-xl font-semibold mb-4">User List</h2>
<button id="fetch-users-btn" class="btn px-4 py-2 rounded-md text-white font-medium">Fetch Users</button>
<div id="user-list" class="mt-4 grid grid-cols-1 sm:grid-cols-2 gap-4">
<!-- User data will be injected here -->
<div id="loader" class="hidden">Loading...</div>
</div>
</div>
<!-- Card 2: Quick Calculator -->
<div class="bg-white p-6 rounded-lg shadow-md">
<h2 class="text-xl font-semibold mb-4">Cost Calculator</h2>
<form id="calculator-form">
<div class="mb-4">
<label for="quantity" class="block text-sm font-medium text-gray-700">Quantity</label>
<input type="number" id="quantity" value="10" class="mt-1 block w-full px-3 py-2 bg-white border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500">
</div>
<div class="mb-4">
<label for="price" class="block text-sm font-medium text-gray-700">Price per Item ($)</label>
<input type="text" id="price" value="5.50" class="mt-1 block w-full px-3 py-2 bg-white border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500">
</div>
<button id="calculate-btn" type="submit" class="btn w-full px-4 py-2 rounded-md text-white font-medium">Calculate Total</button>
<p class="mt-4 text-lg font-bold">Total: $<span id="total-cost">0</span></p>
</form>
</div>
<!-- Card 3: Layout & Style Test -->
<div class="md:col-span-3 bg-white p-6 rounded-lg shadow-md">
<h2 class="text-xl font-semibold mb-4">Action Center</h2>
<div class="flex"> <!-- This container has the layout issue -->
<div class="bg-gray-200 p-4 rounded-lg m-2 w-1/2">Item 1</div>
<div class="bg-gray-200 p-4 rounded-lg m-2 w-1/2">Item 2</div>
<div class="bg-gray-200 p-4 rounded-lg m-2 w-1/2">Item 3</div>
<div class="bg-gray-200 p-4 rounded-lg m-2 w-1/2">Item 4</div>
</div>
<button class="btn btn-important mt-4 px-4 py-2 rounded-md font-medium">Important Action</button>
</div>
</main>
</div>
<script>
// --- Bug Section ---
// 1. User Fetching Logic
const fetchBtn = document.getElementById('fetch-users-btn');
const userList = document.getElementById('user-list');
const loader = document.getElementById('loader');
// The API endpoint URL is incorrect.
const API_URL = 'https://jsonplaceholder.typicode.com/user'; // Intentionally wrong
fetchBtn.addEventListener('click', async () => {
loader.classList.remove('hidden');
try {
const response = await fetch(API_URL);
const users = await response.json();
// Logical issue: Render logic runs even if the fetch fails and throws.
// Also, it doesn't clear previous results.
renderUsers(users);
} catch (error) {
userList.innerHTML = '<p class="text-red-500">Failed to fetch users.</p>';
} finally {
// Bug: Loader is not hidden if an error occurs.
}
});
function renderUsers(users) {
userList.innerHTML = ''; // Clear loader and previous content
// Bug: The logic only displays a subset of users due to a flawed loop.
for (let i = 0; i < 5; i++) {
const user = users[i];
if(user) {
const userCard = document.createElement('div');
userCard.className = 'p-4 border rounded-lg';
userCard.innerHTML = `<h3 class="font-bold">${user.name}</h3><p class="text-sm text-gray-600">${user.email}</p>`;
userList.appendChild(userCard);
}
}
loader.classList.add('hidden');
}
// 2. Calculator Logic
const calculatorForm = document.getElementById('calculator-form');
const quantityInput = document.getElementById('quantity');
const priceInput = document.getElementById('price');
const totalCostEl = document.getElementById('total-cost');
calculatorForm.addEventListener('submit', (event) => {
// Bug: Missing event.preventDefault() causes the form to submit and page to reload.
const quantity = quantityInput.value;
// Bug: priceInput is a text input, its value is a string, leading to incorrect math.
const price = priceInput.value;
// The calculation will be incorrect (e.g., string concatenation or NaN).
const total = quantity * price;
// toFixed can throw an error if total is not a number.
totalCostEl.textContent = total.toFixed(2);
});
// 3. CSS & Layout
// The container for the "Action Center" items is a flex container, but it's
// missing a property to allow wrapping on smaller screens, causing overflow.
// See the <div class="flex"> in the HTML.
// The "Important Action" button has the class "btn-important" which should
// make it red, but a more specific CSS rule is overriding it. See <style> tag.
</script>
</body>
</html>