playground.shiny.space/items.html
Lucas 7a4fa4b312 Fix dark mode flash by inlining critical script
- Move dark mode detection to inline script in HTML head
- Prevents white flash in Firefox by applying theme before render
- Clean up redundant code in dark-mode.js
- Apply fix to all HTML pages for consistent behavior

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-06-14 04:09:18 +02:00

157 lines
No EOL
5.2 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Items Management - Test</title>
<link rel="stylesheet" href="styles.css">
<script>
// Apply dark mode immediately to prevent flash
if (localStorage.getItem('theme') === 'dark') {
document.documentElement.setAttribute('data-theme', 'dark');
}
</script>
</head>
<body>
<button class="dark-mode-toggle" onclick="toggleDarkMode()">🌙</button>
<div class="container">
<h1>Items Management Test</h1>
<div class="section">
<h2>Add New Item</h2>
<div class="form-group">
<input type="text" id="itemName" placeholder="Enter item name" maxlength="100">
<button onclick="createItem()">Add Item</button>
</div>
</div>
<div class="section">
<h2>Items List</h2>
<div id="itemsList" class="items-container">
<p class="loading">Loading items...</p>
</div>
</div>
<div class="section">
<a href="index.html" class="back-button">← Back to Index</a>
</div>
</div>
<script>
let items = [];
// Load items when page loads
document.addEventListener('DOMContentLoaded', function() {
loadItems();
});
// Load all items from API
async function loadItems() {
try {
const response = await fetch('/api/items');
if (!response.ok) {
throw new Error('Failed to fetch items');
}
items = await response.json();
displayItems();
} catch (error) {
console.error('Error loading items:', error);
document.getElementById('itemsList').innerHTML = '<p class="error">Failed to load items</p>';
}
}
// Display items in the list
function displayItems() {
const itemsList = document.getElementById('itemsList');
if (items.length === 0) {
itemsList.innerHTML = '<p class="empty">No items found. Add some items to get started!</p>';
return;
}
let html = '';
items.forEach(item => {
html += `
<div class="item-row">
<span class="item-name">${escapeHtml(item.name)}</span>
<span class="item-id">#${item.id}</span>
<button onclick="deleteItem(${item.id})" class="delete-btn">Delete</button>
</div>
`;
});
itemsList.innerHTML = html;
}
// Create new item
async function createItem() {
const nameInput = document.getElementById('itemName');
const name = nameInput.value.trim();
if (!name) {
alert('Please enter an item name');
return;
}
try {
const response = await fetch('/api/items', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ name: name })
});
if (!response.ok) {
const error = await response.json();
throw new Error(error.error || 'Failed to create item');
}
nameInput.value = '';
loadItems(); // Reload the list
} catch (error) {
console.error('Error creating item:', error);
alert('Failed to create item: ' + error.message);
}
}
// Delete item
async function deleteItem(id) {
if (!confirm('Are you sure you want to delete this item?')) {
return;
}
try {
const response = await fetch(`/api/items/${id}`, {
method: 'DELETE'
});
if (!response.ok) {
const error = await response.json();
throw new Error(error.error || 'Failed to delete item');
}
loadItems(); // Reload the list
} catch (error) {
console.error('Error deleting item:', error);
alert('Failed to delete item: ' + error.message);
}
}
// Handle Enter key in input field
document.getElementById('itemName').addEventListener('keypress', function(e) {
if (e.key === 'Enter') {
createItem();
}
});
// Escape HTML to prevent XSS
function escapeHtml(text) {
const div = document.createElement('div');
div.textContent = text;
return div.innerHTML;
}
</script>
<script src="dark-mode.js"></script>
</body>
</html>