App HTML
App HTML
DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Catálogo Digital Pro</title>
<meta name="theme-color" content="#4e73df">
<meta name="description" content="Catálogo digital con capacidad de edición y
organización automática">
<link rel="manifest" id="appManifest">
<link rel="icon" href="data:image/svg+xml,<svg
📱
xmlns=%22[Link] viewBox=%220 0 100 100%22><text
y=%22.9em%22 font-size=%2290%22> </text></svg>">
<link href="[Link]
rel="stylesheet">
<link rel="stylesheet"
href="[Link]
<style>
:root {
--primary-color: #4e73df;
--secondary-color: #f8f9fc;
--accent-color: #36b9cc;
}
body {
background-color: #f8f9fc;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
padding-top: 56px;
}
.navbar {
background: linear-gradient(90deg, var(--primary-color) 0%, #224abe 100%);
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}
.catalog-item {
transition: transform 0.3s;
border: none;
border-radius: 10px;
box-shadow: 0 0.15rem 1.75rem 0 rgba(58, 59, 69, 0.15);
}
.catalog-item:hover {
transform: translateY(-5px);
}
.category-badge {
position: absolute;
top: 10px;
right: 10px;
}
.upload-area {
border: 2px dashed #ccc;
border-radius: 10px;
padding: 25px;
text-align: center;
background-color: var(--secondary-color);
cursor: pointer;
}
.upload-area:hover {
border-color: var(--primary-color);
}
.search-box {
position: relative;
}
.search-box input {
border-radius: 20px;
padding-left: 45px;
}
.search-box i {
position: absolute;
left: 20px;
top: 12px;
color: #b7b9cc;
}
.btn-primary {
background-color: var(--primary-color);
border-color: var(--primary-color);
}
.btn-primary:hover {
background-color: #224abe;
border-color: #224abe;
}
.ai-generator {
background-color: #f0f8ff;
border-radius: 10px;
padding: 20px;
margin-bottom: 20px;
}
.install-btn {
position: fixed;
bottom: 20px;
right: 20px;
z-index: 1000;
border-radius: 50%;
width: 60px;
height: 60px;
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.3);
display: flex;
align-items: center;
justify-content: center;
}
.offline-alert {
position: fixed;
top: 70px;
left: 0;
right: 0;
z-index: 1050;
border-radius: 0;
display: none;
}
.download-section {
background: linear-gradient(135deg, var(--primary-color) 0%, #224abe 100%);
border-radius: 10px;
padding: 25px;
color: white;
margin-bottom: 25px;
}
<div class="mb-3">
<label for="productCategory" class="form-label">Categoría</label>
<select class="form-select" id="productCategory" required>
<option value="">Seleccionar categoría...</option>
<option value="electronics">Electrónicos</option>
<option value="clothing">Ropa</option>
<option value="books">Libros</option>
<option value="home">Hogar</option>
</select>
</div>
<div class="mb-3">
<label for="productDescription" class="form-label">Descripción</label>
<textarea class="form-control" id="productDescription"
rows="3"></textarea>
</div>
<div class="mb-3">
<label class="form-label">Imagen o Video</label>
<div class="upload-area" id="uploadArea">
<i class="fas fa-cloud-upload-alt fa-3x mb-3"></i>
<p>Haga clic o arrastre un archivo aquí para subirlo</p>
<input type="file" id="fileInput" hidden accept="image/*,video/*">
<div id="previewContainer" class="mt-3"></div>
</div>
</div>
<div class="mb-3">
<label for="productPrice" class="form-label">Precio</label>
<input type="number" class="form-control" id="productPrice" step="0.01">
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary"
data-bs-dismiss="modal">Cancelar</button>
<button type="button" class="btn btn-primary" id="saveProduct">Guardar
Producto</button>
</div>
</div>
</div>
</div>
<script
src="[Link]
<script>
// Sample product data
const products = [
{
id: 1,
name: "Smartphone XL",
category: "electronics",
description: "Último modelo con cámara de alta resolución y batería de larga
duración.",
image: "[Link]
price: 599.99
},
{
id: 2,
name: "Abrigo de Invierno",
category: "clothing",
description: "Abrigo abrigado perfecto para los meses fríos, disponible en varios
colores.",
image: "[Link]
price: 89.99
},
{
id: 3,
name: "Novela Best Seller",
category: "books",
description: "La novela más vendida del año, con una trama emocionante que te
atrapará.",
image: "[Link]
price: 24.99
},
{
id: 4,
name: "Silla Ergonómica",
category: "home",
description: "Silla de oficina ergonómica con soporte lumbar ajustable para mayor
comodidad.",
image: "[Link]
price: 199.99
}
];
if ([Link] === 0) {
[Link] = `
<div class="col-12 text-center py-5">
<i class="fas fa-box-open fa-3x text-muted mb-3"></i>
<h4 class="text-muted">No se encontraron productos</h4>
<p>Intenta ajustar los filtros de búsqueda o agrega un nuevo producto.</p>
</div>
`;
return;
}
[Link](product => {
const categoryNames = {
'electronics': 'Electrónicos',
'clothing': 'Ropa',
'books': 'Libros',
'home': 'Hogar'
};
const col = [Link]('div');
[Link] = 'col-md-6 col-lg-4 col-xl-3 mb-4';
[Link] = `
<div class="card catalog-item h-100">
<span class="category-badge badge
bg-primary">${categoryNames[[Link]]}</span>
<img src="${[Link]}" class="card-img-top product-image"
alt="${[Link]}">
<div class="card-body">
<h5 class="card-title">${[Link]}</h5>
<p class="card-text">${[Link]}</p>
<div class="d-flex justify-content-between align-items-center">
<span class="h5 mb-0">$${[Link](2)}</span>
<div>
<button class="btn btn-sm btn-outline-primary edit-btn"
data-id="${[Link]}">
<i class="fas fa-edit"></i>
</button>
<button class="btn btn-sm btn-outline-danger delete-btn"
data-id="${[Link]}">
<i class="fas fa-trash"></i>
</button>
</div>
</div>
</div>
</div>
`;
[Link](col);
});
[Link]('.delete-btn').forEach(btn => {
[Link]('click', (e) => {
const productId = [Link]('.delete-btn').[Link];
deleteProduct(productId);
});
});
}
renderProducts(filteredProducts);
}
switch(sortOption) {
case 'name':
[Link]((a, b) => [Link]([Link]));
break;
case 'name-desc':
[Link]((a, b) => [Link]([Link]));
break;
case 'category':
[Link]((a, b) => [Link]([Link]));
break;
case 'newest':
// Assuming newer products have higher IDs
[Link]((a, b) => [Link] - [Link]);
break;
}
renderProducts(sortedProducts);
}
[Link]('click', () => {
[Link]();
});
[Link]('dragleave', () => {
[Link]('bg-light');
});
if ([Link]) {
[Link] = [Link];
handleFilePreview([Link][0]);
}
});
[Link]('change', () => {
if ([Link]) {
handleFilePreview([Link][0]);
}
});
}
function handleFilePreview(file) {
const previewContainer = [Link]('previewContainer');
[Link] = '';
if ([Link]('image/')) {
const img = [Link]('img');
[Link] = [Link](file);
[Link] = 'img-fluid rounded';
[Link] = '150px';
[Link](img);
} else if ([Link]('video/')) {
const video = [Link]('video');
[Link] = [Link](file);
[Link] = true;
[Link] = 'img-fluid rounded';
[Link] = '150px';
[Link](video);
}
}
// Function to add new product
function setupAddProduct() {
[Link]('saveProduct').addEventListener('click', () => {
const name = [Link]('productName').value;
const category = [Link]('productCategory').value;
const description = [Link]('productDescription').value;
const price = parseFloat([Link]('productPrice').value);
if (!name || !category) {
alert('Por favor, complete al menos el nombre y la categoría del producto.');
return;
}
const newProduct = {
id: [Link] > 0 ? [Link](...[Link](p => [Link])) + 1 : 1,
name,
category,
description,
image,
price
};
[Link](newProduct);
renderProducts(products);
[Link]([Link]('addProductModal')).hide();
[Link]('productForm').reset();
[Link]('previewContainer').innerHTML = '';
// PWA functionality
function setupPWA() {
let deferredPrompt;
const installButton = [Link]('installButton');
const downloadBtn = [Link]('downloadBtn');
[Link]('click', () => {
// Hide the install button
[Link] = 'none';
// Show the install prompt
[Link]();
// Wait for the user to respond to the prompt
[Link]((choiceResult) => {
if ([Link] === 'accepted') {
[Link]('User accepted the install prompt');
} else {
[Link]('User dismissed the install prompt');
}
deferredPrompt = null;
});
});
[Link]('offline', () => {
[Link]('offlineAlert').[Link] = 'block';
});
// Share functionality
[Link]('shareBtn').addEventListener('click', async () => {
try {
if ([Link]) {
await [Link]({
title: 'Catálogo Digital Pro',
text: 'Mira este increíble catálogo digital que puedes instalar en tu
dispositivo',
url: [Link]
});
} else {
alert('Compartir no es compatible en tu navegador. Copia la URL para
compartirla.');
}
} catch (error) {
[Link]('Error sharing:', error);
}
});
}