chore: initialize project repository with core extension files
- Add .gitignore to exclude node_modules, dist, logs, and system files - Add comprehensive project documentation including README, deployment guide, and development setup - Add .kiro project specifications for amazon-product-bar-extension, appwrite-cloud-storage, appwrite-userid-repair, blacklist-feature, and enhanced-item-management - Add .kiro steering documents for product, structure, styling, and tech guidelines - Add VSCode settings configuration for consistent development environment - Add manifest.json and babel/vite configuration for extension build setup - Add complete source code implementation including AppWrite integration, storage managers, UI components, and services - Add comprehensive test suite with Jest configuration and 30+ test files covering all major modules - Add test HTML files for integration testing and validation - Add coverage reports and build validation scripts - Add AppWrite setup and repair documentation for database schema management - Add migration guides and responsive accessibility implementation documentation - Establish foundation for Amazon product bar extension with full feature set including blacklist management, enhanced item workflows, and real-time synchronization
This commit is contained in:
301
test-enhanced-items-panel.html
Normal file
301
test-enhanced-items-panel.html
Normal file
@@ -0,0 +1,301 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Enhanced Items Panel Test</title>
|
||||
<style>
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 20px;
|
||||
background: #1a1a1a;
|
||||
color: white;
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
||||
}
|
||||
|
||||
.test-container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.test-header {
|
||||
text-align: center;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.panel-container {
|
||||
width: 100%;
|
||||
height: 80vh;
|
||||
border: 2px solid #333;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
<link rel="stylesheet" href="src/EnhancedItemsPanel.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="test-container">
|
||||
<div class="test-header">
|
||||
<h1>Enhanced Items Panel Test</h1>
|
||||
<p>Testing the Enhanced Items Panel UI and functionality</p>
|
||||
</div>
|
||||
|
||||
<div class="panel-container" id="panel-container">
|
||||
<!-- Enhanced Items Panel will be inserted here -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="module">
|
||||
// Mock dependencies for testing
|
||||
class MockProductExtractor {
|
||||
async extractProductData(url) {
|
||||
// Simulate extraction delay
|
||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||
|
||||
return {
|
||||
title: 'Samsung Galaxy S21 Ultra 5G Smartphone 128GB',
|
||||
price: '899.99',
|
||||
currency: 'EUR',
|
||||
imageUrl: 'https://via.placeholder.com/150x150?text=Product'
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
class MockMistralAIService {
|
||||
async generateTitleSuggestions(originalTitle, apiKey) {
|
||||
// Simulate AI processing delay
|
||||
await new Promise(resolve => setTimeout(resolve, 2000));
|
||||
|
||||
return [
|
||||
'Samsung Galaxy S21 Ultra - Premium 5G Flagship',
|
||||
'Galaxy S21 Ultra: High-End Android Smartphone',
|
||||
'Samsung S21 Ultra - Professional Mobile Device'
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
class MockTitleSelectionManager {
|
||||
constructor() {
|
||||
this.onTitleSelectedCallback = null;
|
||||
}
|
||||
|
||||
createSelectionUI(suggestions, originalTitle) {
|
||||
const container = document.createElement('div');
|
||||
container.className = 'title-selection-container';
|
||||
container.style.cssText = `
|
||||
background: #2a2a2a;
|
||||
border: 1px solid #444;
|
||||
border-radius: 8px;
|
||||
padding: 1.5rem;
|
||||
margin: 1rem 0;
|
||||
`;
|
||||
|
||||
container.innerHTML = `
|
||||
<h3 style="margin: 0 0 1rem 0; color: #fff;">Titel auswählen:</h3>
|
||||
<div class="title-options">
|
||||
${suggestions.map((suggestion, index) => `
|
||||
<div class="title-option" data-index="${index}" style="
|
||||
padding: 1rem;
|
||||
border: 2px solid #444;
|
||||
border-radius: 6px;
|
||||
margin-bottom: 0.5rem;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
">
|
||||
<span style="font-weight: 600; color: #007acc; display: block; margin-bottom: 0.25rem;">
|
||||
KI-Vorschlag ${index + 1}:
|
||||
</span>
|
||||
<span style="font-size: 1.1rem; color: #fff;">${suggestion}</span>
|
||||
</div>
|
||||
`).join('')}
|
||||
<div class="title-option" data-index="3" style="
|
||||
padding: 1rem;
|
||||
border: 2px solid #444;
|
||||
border-radius: 6px;
|
||||
margin-bottom: 0.5rem;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
">
|
||||
<span style="font-weight: 600; color: #28a745; display: block; margin-bottom: 0.25rem;">
|
||||
Original:
|
||||
</span>
|
||||
<span style="font-size: 1.1rem; color: #fff;">${originalTitle}</span>
|
||||
</div>
|
||||
</div>
|
||||
<button class="confirm-btn" style="
|
||||
padding: 0.75rem 1.5rem;
|
||||
background: #007acc;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
margin-top: 1rem;
|
||||
">Auswahl bestätigen</button>
|
||||
`;
|
||||
|
||||
// Add click handlers
|
||||
const options = container.querySelectorAll('.title-option');
|
||||
let selectedIndex = 0;
|
||||
|
||||
options.forEach((option, index) => {
|
||||
option.addEventListener('click', () => {
|
||||
options.forEach(opt => opt.style.borderColor = '#444');
|
||||
option.style.borderColor = '#007acc';
|
||||
selectedIndex = index;
|
||||
});
|
||||
});
|
||||
|
||||
// Select first option by default
|
||||
options[0].style.borderColor = '#007acc';
|
||||
|
||||
const confirmBtn = container.querySelector('.confirm-btn');
|
||||
confirmBtn.addEventListener('click', () => {
|
||||
const selectedOption = options[selectedIndex];
|
||||
const titleText = selectedOption.querySelector('span:last-child').textContent;
|
||||
if (this.onTitleSelectedCallback) {
|
||||
this.onTitleSelectedCallback(titleText);
|
||||
}
|
||||
});
|
||||
|
||||
return container;
|
||||
}
|
||||
|
||||
onTitleSelected(callback) {
|
||||
this.onTitleSelectedCallback = callback;
|
||||
}
|
||||
|
||||
showTitleSelection(container) {
|
||||
// Already visible when created
|
||||
}
|
||||
}
|
||||
|
||||
class MockUrlValidator {
|
||||
static validateAmazonUrl(url) {
|
||||
if (!url || !url.includes('amazon')) {
|
||||
return {
|
||||
isValid: false,
|
||||
error: 'Bitte geben Sie eine gültige Amazon-URL ein.'
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
isValid: true,
|
||||
cleanUrl: url,
|
||||
asin: 'B08N5WRWNW'
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
class MockEnhancedStorageManager {
|
||||
constructor() {
|
||||
this.items = [
|
||||
{
|
||||
id: 'B08N5WRWNW',
|
||||
amazonUrl: 'https://amazon.de/dp/B08N5WRWNW',
|
||||
originalTitle: 'Samsung Galaxy S21 Ultra 5G Smartphone 128GB',
|
||||
customTitle: 'Samsung Galaxy S21 Ultra - Premium 5G Flagship',
|
||||
price: '899.99',
|
||||
currency: 'EUR',
|
||||
titleSuggestions: [
|
||||
'Samsung Galaxy S21 Ultra - Premium 5G Flagship',
|
||||
'Galaxy S21 Ultra: High-End Android Smartphone',
|
||||
'Samsung S21 Ultra - Professional Mobile Device'
|
||||
],
|
||||
createdAt: new Date('2024-01-15T10:30:00Z'),
|
||||
updatedAt: new Date('2024-01-15T10:30:00Z')
|
||||
},
|
||||
{
|
||||
id: 'B07XJ8C8F5',
|
||||
amazonUrl: 'https://amazon.de/dp/B07XJ8C8F5',
|
||||
originalTitle: 'Apple iPhone 13 Pro Max 256GB',
|
||||
customTitle: 'iPhone 13 Pro Max - Premium Apple Smartphone',
|
||||
price: '1199.00',
|
||||
currency: 'EUR',
|
||||
titleSuggestions: [
|
||||
'iPhone 13 Pro Max - Premium Apple Smartphone',
|
||||
'Apple iPhone 13 Pro Max: Professional Mobile',
|
||||
'iPhone 13 Pro Max - High-End iOS Device'
|
||||
],
|
||||
createdAt: new Date('2024-01-14T15:20:00Z'),
|
||||
updatedAt: new Date('2024-01-14T15:20:00Z')
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
async getItemsChronological() {
|
||||
return [...this.items].sort((a, b) => new Date(b.createdAt) - new Date(a.createdAt));
|
||||
}
|
||||
|
||||
async getEnhancedItem(id) {
|
||||
return this.items.find(item => item.id === id) || null;
|
||||
}
|
||||
|
||||
async saveEnhancedItem(item) {
|
||||
const existingIndex = this.items.findIndex(i => i.id === item.id);
|
||||
if (existingIndex >= 0) {
|
||||
this.items[existingIndex] = { ...item };
|
||||
} else {
|
||||
this.items.push({ ...item });
|
||||
}
|
||||
}
|
||||
|
||||
async updateEnhancedItem(id, updates) {
|
||||
const index = this.items.findIndex(item => item.id === id);
|
||||
if (index >= 0) {
|
||||
this.items[index] = { ...this.items[index], ...updates, updatedAt: new Date() };
|
||||
}
|
||||
}
|
||||
|
||||
async deleteEnhancedItem(id) {
|
||||
this.items = this.items.filter(item => item.id !== id);
|
||||
}
|
||||
|
||||
async getSettings() {
|
||||
return {
|
||||
mistralApiKey: 'test-api-key',
|
||||
autoExtractEnabled: true,
|
||||
defaultTitleSelection: 'first',
|
||||
maxRetries: 3,
|
||||
timeoutSeconds: 10
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// Import and setup Enhanced Items Panel Manager
|
||||
import('./src/EnhancedItemsPanelManager.js').then(module => {
|
||||
const { EnhancedItemsPanelManager } = module;
|
||||
|
||||
// Create a custom version with mocked dependencies
|
||||
class TestEnhancedItemsPanelManager extends EnhancedItemsPanelManager {
|
||||
constructor() {
|
||||
super();
|
||||
this.storageManager = new MockEnhancedStorageManager();
|
||||
this.productExtractor = new MockProductExtractor();
|
||||
this.mistralService = new MockMistralAIService();
|
||||
this.titleSelectionManager = new MockTitleSelectionManager();
|
||||
}
|
||||
}
|
||||
|
||||
// Mock UrlValidator globally
|
||||
window.UrlValidator = MockUrlValidator;
|
||||
|
||||
// Create and initialize the panel
|
||||
const panelManager = new TestEnhancedItemsPanelManager();
|
||||
const panelContent = panelManager.createItemsContent();
|
||||
|
||||
const container = document.getElementById('panel-container');
|
||||
container.appendChild(panelContent);
|
||||
|
||||
console.log('Enhanced Items Panel loaded successfully!');
|
||||
}).catch(error => {
|
||||
console.error('Error loading Enhanced Items Panel:', error);
|
||||
document.getElementById('panel-container').innerHTML = `
|
||||
<div style="padding: 2rem; text-align: center; color: #ff6b6b;">
|
||||
<h2>Error Loading Panel</h2>
|
||||
<p>${error.message}</p>
|
||||
</div>
|
||||
`;
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user