0% found this document useful (0 votes)
36 views15 pages

App HTML

The document is an HTML template for a digital catalog application that allows users to edit and organize products. It includes features such as a navigation bar, product search, category filtering, and an AI description generator. The layout is responsive and utilizes Bootstrap for styling, with sections for product display, installation prompts, and a modal for adding new products.

Uploaded by

amorrivero1
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
36 views15 pages

App HTML

The document is an HTML template for a digital catalog application that allows users to edit and organize products. It includes features such as a navigation bar, product search, category filtering, and an AI description generator. The layout is responsive and utilizes Bootstrap for styling, with sections for product display, installation prompts, and a modal for adding new products.

Uploaded by

amorrivero1
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

<!

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;
}

@media (max-width: 768px) {


.product-image {
height: 200px;
object-fit: cover;
}
}
</style>
</head>
<body>
<!-- Navbar -->
<nav class="navbar navbar-expand-lg navbar-dark fixed-top">
<div class="container">
<a class="navbar-brand" href="#">
<i class="fas fa-catalog me-2"></i>Catálogo Digital
</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse"
data-bs-target="#navbarContent">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarContent">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item">
<a class="nav-link active" href="#"><i class="fas fa-home me-1"></i>
Inicio</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#"><i class="fas fa-folder me-1"></i>
Categorías</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#" data-bs-toggle="modal"
data-bs-target="#addProductModal">
<i class="fas fa-plus-circle me-1"></i> Agregar
</a>
</li>
</ul>
<div class="search-box">
<i class="fas fa-search"></i>
<input type="text" class="form-control" placeholder="Buscar productos..."
id="searchInput">
</div>
</div>
</div>
</nav>

<!-- Offline Alert -->


<div class="alert alert-warning offline-alert" id="offlineAlert">
<i class="fas fa-wifi-slash me-2"></i>Estás trabajando sin conexión. Los cambios se
sincronizarán cuando recuperes la conexión.
</div>

<!-- Main Content -->


<div class="container mt-4">
<!-- Download Section -->
<div class="download-section">
<div class="row align-items-center">
<div class="col-md-8">
<h3><i class="fas fa-mobile-alt me-2"></i> Instala nuestra App</h3>
<p>Guarda este catálogo en tu dispositivo móvil para acceder rápidamente,
incluso sin conexión a internet.</p>
<div class="d-flex flex-wrap gap-2">
<button class="btn btn-light" id="downloadBtn">
<i class="fas fa-download me-2"></i>Guardar como App
</button>
<button class="btn btn-outline-light" id="shareBtn">
<i class="fas fa-share-alt me-2"></i>Compartir
</button>
</div>
</div>
<div class="col-md-4 text-center">
<img src="data:image/svg+xml,%3Csvg xmlns='[Link]
viewBox='0 0 100 100'%3E%3Crect width='100' height='100' fill='%23FFF'
rx='15'/%3E%3Ctext x='50' y='50' font-size='50' text-anchor='middle'
dominant-baseline='middle'
fill='%234e73df'%3E%F0%9F%93%81%3C/text%3E%3C/svg%3E"
alt="Logo Catálogo" width="100" class="img-fluid">
</div>
</div>
</div>

<div class="row mb-4">


<div class="col-md-6">
<h2>Mi Catálogo Digital</h2>
</div>
<div class="col-md-3">
<select class="form-select" id="categoryFilter">
<option value="">Todas las categorías</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="col-md-3">
<select class="form-select" id="sortSelect">
<option value="name">Ordenar por nombre (A-Z)</option>
<option value="name-desc">Ordenar por nombre (Z-A)</option>
<option value="category">Ordenar por categoría</option>
<option value="newest">Más recientes primero</option>
</select>
</div>
</div>

<!-- AI Description Generator -->


<div class="ai-generator">
<h5><i class="fas fa-robot me-2"></i> Generador de Descripciones con IA</h5>
<div class="input-group mb-2">
<input type="text" class="form-control" placeholder="Palabras clave para generar
descripción...">
<button class="btn btn-primary">Generar</button>
</div>
<small class="text-muted">La IA creará una descripción atractiva para tu
producto</small>
</div>

<!-- Product Grid -->


<div class="row" id="productGrid">
<!-- Product cards will be generated here -->
</div>
</div>

<!-- Install Button -->


<button class="btn btn-primary install-btn" id="installButton" style="display: none;">
<i class="fas fa-download fa-lg"></i>
</button>

<!-- Add Product Modal -->


<div class="modal fade" id="addProductModal" tabindex="-1"
aria-labelledby="addProductModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="addProductModalLabel">Agregar Nuevo
Producto</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"
aria-label="Close"></button>
</div>
<div class="modal-body">
<form id="productForm">
<div class="mb-3">
<label for="productName" class="form-label">Nombre del
Producto</label>
<input type="text" class="form-control" id="productName" required>
</div>

<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
}
];

// Function to render products


function renderProducts(productsArray) {
const productGrid = [Link]('productGrid');
[Link] = '';

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);
});

// Add event listeners to edit and delete buttons


[Link]('.edit-btn').forEach(btn => {
[Link]('click', (e) => {
const productId = [Link]('.edit-btn').[Link];
editProduct(productId);
});
});

[Link]('.delete-btn').forEach(btn => {
[Link]('click', (e) => {
const productId = [Link]('.delete-btn').[Link];
deleteProduct(productId);
});
});
}

// Function to handle search


function handleSearch() {
const searchText = [Link]('searchInput').[Link]();
const categoryFilter = [Link]('categoryFilter').value;

const filteredProducts = [Link](product => {


const matchesSearch = [Link]().includes(searchText) ||
[Link]().includes(searchText);
const matchesCategory = categoryFilter ? [Link] === categoryFilter :
true;

return matchesSearch && matchesCategory;


});

renderProducts(filteredProducts);
}

// Function to handle sorting


function handleSort() {
const sortOption = [Link]('sortSelect').value;
let sortedProducts = [...products];

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);
}

// Function to handle file upload


function setupFileUpload() {
const uploadArea = [Link]('uploadArea');
const fileInput = [Link]('fileInput');
const previewContainer = [Link]('previewContainer');

[Link]('click', () => {
[Link]();
});

[Link]('dragover', (e) => {


[Link]();
[Link]('bg-light');
});

[Link]('dragleave', () => {
[Link]('bg-light');
});

[Link]('drop', (e) => {


[Link]();
[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;
}

// In a real application, you would upload the file to a server


// For this demo, we're using a placeholder
const image = "[Link]

const newProduct = {
id: [Link] > 0 ? [Link](...[Link](p => [Link])) + 1 : 1,
name,
category,
description,
image,
price
};

[Link](newProduct);
renderProducts(products);

// Close modal and reset form

[Link]([Link]('addProductModal')).hide();
[Link]('productForm').reset();
[Link]('previewContainer').innerHTML = '';

// Show success message


alert('Producto agregado correctamente!');
});
}

// Function to edit product (simplified for demo)


function editProduct(id) {
alert(`Funcionalidad de edición para el producto con ID ${id}. En una aplicación real,
se abriría un formulario de edición.`);
}

// Function to delete product


function deleteProduct(id) {
if (confirm('¿Está seguro de que desea eliminar este producto?')) {
const index = [Link](p => [Link] === parseInt(id));
if (index !== -1) {
[Link](index, 1);
renderProducts(products);
alert('Producto eliminado correctamente!');
}
}
}

// PWA functionality
function setupPWA() {
let deferredPrompt;
const installButton = [Link]('installButton');
const downloadBtn = [Link]('downloadBtn');

// Create manifest dynamically


const manifest = {
"name": "Catálogo Digital Pro",
"short_name": "CataDigital",
"description": "Catálogo digital con capacidad de edición",
"start_url": ".",
"display": "standalone",
"background_color": "#4e73df",
"theme_color": "#4e73df",
"icons": [
{
"src": "data:image/svg+xml,%3Csvg xmlns='[Link]
viewBox='0 0 100 100'%3E%3Crect width='100' height='100' fill='%234e73df'
rx='15'/%3E%3Ctext x='50' y='50' font-size='50' text-anchor='middle'
dominant-baseline='middle'
fill='%23FFF'%3E%F0%9F%93%81%3C/text%3E%3C/svg%3E",
"sizes": "100x100",
"type": "image/svg+xml"
}
]
};

const manifestJson = [Link](manifest);


const manifestContent =
`data:application/manifest+json;charset=utf-8,${encodeURIComponent(manifestJson)}`;
[Link]('appManifest').setAttribute('href', manifestContent);

// Listen for beforeinstallprompt event


[Link]('beforeinstallprompt', (e) => {
// Prevent the mini-infobar from appearing on mobile
[Link]();
// Stash the event so it can be triggered later
deferredPrompt = e;
// Show the install button
[Link] = 'flex';

[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;
});
});

// Also show the download button


[Link]('click', () => {
[Link]();
});
});

// Listen for app installed event


[Link]('appinstalled', () => {
[Link]('PWA was installed');
[Link] = 'none';
deferredPrompt = null;
});

// Handle offline/online status


[Link]('online', () => {
[Link]('offlineAlert').[Link] = 'none';
});

[Link]('offline', () => {
[Link]('offlineAlert').[Link] = 'block';
});

// Check initial connection status


if (![Link]) {
[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);
}
});
}

// Initialize the application


[Link]('DOMContentLoaded', () => {
renderProducts(products);
setupFileUpload();
setupAddProduct();
setupPWA();

// Add event listeners


[Link]('searchInput').addEventListener('input', handleSearch);
[Link]('categoryFilter').addEventListener('change',
handleSearch);
[Link]('sortSelect').addEventListener('change', handleSort);
});
</script>
</body>
</html>

You might also like