Autosave: 20260505-030332

This commit is contained in:
Flatlogic Bot 2026-05-05 03:03:33 +00:00
parent 5a30279f6c
commit 4f3867406b
13 changed files with 735 additions and 89 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

View File

@ -0,0 +1,10 @@
CREATE TABLE IF NOT EXISTS marketing_videos (
id INT AUTO_INCREMENT PRIMARY KEY,
producto_id INT NULL,
foto_producto VARCHAR(255) NULL,
instrucciones TEXT NULL,
link_video VARCHAR(255) NULL,
estado ENUM('Pendiente', 'En Proceso', 'Terminado', 'Aprobado') DEFAULT 'Pendiente',
fecha_creacion TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (producto_id) REFERENCES products(id) ON DELETE SET NULL
);

View File

@ -0,0 +1,7 @@
ALTER TABLE marketing_videos
ADD COLUMN fecha_entrega DATE NULL AFTER fecha_creacion,
ADD COLUMN angulo_video TEXT NULL AFTER instrucciones,
ADD COLUMN link_inspiracion_landing VARCHAR(255) NULL AFTER angulo_video,
ADD COLUMN link_inspiracion_video VARCHAR(255) NULL AFTER link_inspiracion_landing,
ADD COLUMN link_landing VARCHAR(255) NULL AFTER link_video,
ADD COLUMN orden INT DEFAULT 0 AFTER id;

View File

@ -0,0 +1 @@
ALTER TABLE marketing_videos ADD COLUMN link_flyer VARCHAR(255) NULL AFTER link_landing;

View File

@ -0,0 +1 @@
ALTER TABLE marketing_videos ADD COLUMN material TEXT AFTER foto_producto;

View File

@ -0,0 +1,7 @@
CREATE TABLE IF NOT EXISTS marketing_assets (
id INT AUTO_INCREMENT PRIMARY KEY,
nombre VARCHAR(255) NOT NULL,
categoria ENUM('Logo', 'Intro/Outro', 'Música', 'Gráficos', 'Otros') DEFAULT 'Otros',
archivo_path VARCHAR(255) NOT NULL,
fecha_subida TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

View File

@ -0,0 +1,24 @@
<?php
include 'db/config.php';
$db = db();
if (isset($_GET['id'])) {
$id = $_GET['id'];
// Obtener la ruta del archivo para borrarlo del servidor
$stmt = $db->prepare("SELECT archivo_path FROM marketing_assets WHERE id = ?");
$stmt->execute([$id]);
$asset = $stmt->fetch(PDO::FETCH_ASSOC);
if ($asset) {
if (file_exists($asset['archivo_path'])) {
unlink($asset['archivo_path']);
}
$stmt = $db->prepare("DELETE FROM marketing_assets WHERE id = ?");
$stmt->execute([$id]);
}
}
header("Location: marketing_assets.php");
exit;

View File

@ -1,14 +1,148 @@
<?php
$pageTitle = "Biblioteca de Assets";
include 'db/config.php';
include 'layout_header.php';
$db = db();
// Obtener todos los assets
$stmt = $db->query("SELECT * FROM marketing_assets ORDER BY categoria ASC, nombre ASC");
$assets = $stmt->fetchAll(PDO::FETCH_ASSOC);
// Agrupar por categoría
$categorias = [
'Logo' => [],
'Intro/Outro' => [],
'Música' => [],
'Gráficos' => [],
'Otros' => []
];
foreach ($assets as $asset) {
$categorias[$asset['categoria']][] = $asset;
}
?>
<div class="card">
<div class="card-body">
<h5 class="card-title">Biblioteca de Recursos de Marketing</h5>
<p>Aquí podrás subir y organizar logos, intros de video, música y otros materiales que la editora deba utilizar de forma recurrente.</p>
<div class="alert alert-info">
<i class="bi bi-info-circle me-1"></i> Esta sección está en desarrollo. Pronto podrás gestionar tus archivos aquí.
<main id="main" class="main">
<div class="pagetitle d-flex justify-content-between align-items-center">
<div>
<h1>Biblioteca de Assets</h1>
<nav>
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="index.php">Home</a></li>
<li class="breadcrumb-item">Marketing</li>
<li class="breadcrumb-item active">Assets</li>
</ol>
</nav>
</div>
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#subirAssetModal">
<i class="bi bi-cloud-arrow-up"></i> Subir Nuevo Recurso
</button>
</div>
<section class="section">
<div class="row">
<?php foreach ($categorias as $cat => $items): ?>
<div class="col-12 mb-4">
<div class="card">
<div class="card-header d-flex justify-content-between align-items-center bg-light">
<h5 class="card-title mb-0 py-0"><?php echo $cat; ?> <span class="badge bg-secondary ms-2"><?php echo count($items); ?></span></h5>
</div>
<div class="card-body pt-3">
<?php if (empty($items)): ?>
<p class="text-muted mb-0">No hay archivos en esta categoría.</p>
<?php else: ?>
<div class="table-responsive">
<table class="table table-hover align-middle">
<thead>
<tr>
<th>Nombre</th>
<th>Fecha</th>
<th class="text-end">Acciones</th>
</tr>
</thead>
<tbody>
<?php foreach ($items as $item): ?>
<tr>
<td>
<div class="d-flex align-items-center">
<?php
$ext = pathinfo($item['archivo_path'], PATHINFO_EXTENSION);
$icon = 'bi-file-earmark';
if (in_array($ext, ['jpg', 'jpeg', 'png', 'svg'])) $icon = 'bi-image';
if (in_array($ext, ['mp4', 'mov', 'avi'])) $icon = 'bi-play-btn';
if (in_array($ext, ['mp3', 'wav'])) $icon = 'bi-music-note-beamed';
?>
<i class="bi <?php echo $icon; ?> fs-4 me-3 text-primary"></i>
<span><?php echo htmlspecialchars($item['nombre']); ?></span>
</div>
</td>
<td><?php echo date('d/m/Y', strtotime($item['fecha_subida'])); ?></td>
<td class="text-end">
<a href="<?php echo $item['archivo_path']; ?>" download class="btn btn-sm btn-outline-success" title="Descargar">
<i class="bi bi-download"></i>
</a>
<button class="btn btn-sm btn-outline-danger" onclick="eliminarAsset(<?php echo $item['id']; ?>)" title="Eliminar">
<i class="bi bi-trash"></i>
</button>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<?php endif; ?>
</div>
</div>
</div>
<?php endforeach; ?>
</div>
</section>
<!-- Modal Subir Asset -->
<div class="modal fade" id="subirAssetModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<form action="save_marketing_asset.php" method="POST" enctype="multipart/form-data">
<div class="modal-header">
<h5 class="modal-title">Subir Recurso</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<div class="mb-3">
<label class="form-label">Nombre del Recurso</label>
<input type="text" name="nombre" class="form-control" placeholder="Ej: Logo Principal Blanco" required>
</div>
<div class="mb-3">
<label class="form-label">Categoría</label>
<select name="categoria" class="form-select" required>
<option value="Logo">Logo</option>
<option value="Intro/Outro">Intro/Outro</option>
<option value="Música">Música</option>
<option value="Gráficos">Gráficos</option>
<option value="Otros">Otros</option>
</select>
</div>
<div class="mb-3">
<label class="form-label">Archivo</label>
<input type="file" name="archivo" class="form-control" required>
<div class="form-text">Soporta imágenes, videos y audio.</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cerrar</button>
<button type="submit" class="btn btn-primary">Subir Archivo</button>
</div>
</form>
</div>
</div>
</div>
</div>
</main>
<script>
function eliminarAsset(id) {
if (confirm('¿Estás seguro de que deseas eliminar este recurso?')) {
window.location.href = 'delete_marketing_asset.php?id=' + id;
}
}
</script>
<?php include 'layout_footer.php'; ?>

View File

@ -13,73 +13,186 @@ $productos = $stmt_products->fetchAll(PDO::FETCH_ASSOC);
$stmt_videos = $db->query("SELECT mv.*, p.nombre as nombre_producto
FROM marketing_videos mv
LEFT JOIN products p ON mv.producto_id = p.id
ORDER BY mv.fecha_creacion DESC");
ORDER BY mv.orden ASC, mv.fecha_creacion DESC");
$videos = $stmt_videos->fetchAll(PDO::FETCH_ASSOC);
?>
<style>
.table-excel {
font-size: 0.85rem;
}
.table-excel th {
background-color: #f8f9fa;
border-bottom: 2px solid #dee2e6;
white-space: nowrap;
text-transform: uppercase;
font-weight: 600;
color: #495057;
}
.table-excel td {
vertical-align: middle;
border-bottom: 1px solid #eee;
}
.img-preview {
width: 50px;
height: 50px;
object-fit: cover;
border-radius: 4px;
cursor: pointer;
}
.link-icon {
font-size: 1.1rem;
color: #0d6efd;
}
.link-icon:hover {
color: #0a58ca;
}
.status-badge {
font-size: 0.75rem;
padding: 0.35em 0.65em;
}
.editable:hover {
background-color: #f1f3f5;
cursor: pointer;
}
.inline-edit-input {
width: 100%;
padding: 2px 5px;
font-size: 0.85rem;
border: 1px solid #0d6efd;
border-radius: 3px;
}
</style>
<div class="d-flex justify-content-between align-items-center mb-4">
<h2>Gestión de Producción</h2>
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#nuevoVideoModal">
<i class="fas fa-plus"></i> Nuevo Pedido de Video
</button>
<div>
<h2 class="mb-0">Producción de Video</h2>
<p class="text-muted small">Vista de control estilo Excel</p>
</div>
<div>
<a href="marketing_assets.php" class="btn btn-outline-secondary me-2">
<i class="fas fa-folder-open"></i> Biblioteca de Assets
</a>
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#nuevoVideoModal">
<i class="fas fa-plus"></i> Nuevo Pedido
</button>
</div>
</div>
<?php if (isset($_GET['success'])): ?>
<div class="alert alert-success alert-dismissible fade show" role="alert">
¡Pedido creado con éxito!
¡Operación realizada con éxito!
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
<?php endif; ?>
<div class="row">
<?php if (empty($videos)): ?>
<div class="col-12 text-center py-5">
<i class="fas fa-video fa-4x text-muted mb-3"></i>
<p class="text-muted">No hay pedidos de video registrados aún.</p>
<div class="card shadow-sm border-0">
<div class="card-body p-0">
<div class="table-responsive">
<table class="table table-hover table-excel mb-0">
<thead>
<tr>
<th class="text-center">Orden</th>
<th>Fecha Entrega</th>
<th>Producto</th>
<th class="text-center">Imagen</th>
<th>Material</th>
<th>Ángulo</th>
<th class="text-center">Insp. Landing</th>
<th class="text-center">Insp. Video</th>
<th class="text-center">Link Video</th>
<th class="text-center">Link Landing</th>
<th class="text-center">Link Flyer</th>
<th class="text-center">Estado</th>
<th class="text-center">Acción</th>
</tr>
</thead>
<tbody>
<?php if (empty($videos)): ?>
<tr>
<td colspan="11" class="text-center py-4 text-muted">No hay pedidos registrados.</td>
</tr>
<?php else: ?>
<?php foreach ($videos as $v): ?>
<tr>
<td class="text-center fw-bold text-primary"><?php echo $v['orden']; ?></td>
<td>
<?php echo $v['fecha_entrega'] ? date('d/m/Y', strtotime($v['fecha_entrega'])) : '<span class="text-muted">-</span>'; ?>
</td>
<td class="fw-bold"><?php echo htmlspecialchars($v['nombre_producto'] ?: 'General'); ?></td>
<td class="text-center">
<?php if ($v['foto_producto']): ?>
<img src="<?php echo $v['foto_producto']; ?>" class="img-preview" alt="Ref" onclick="window.open(this.src)">
<?php else: ?>
<span class="text-muted small">Sin foto</span>
<?php endif; ?>
</td>
<td class="editable" data-id="<?php echo $v['id']; ?>" data-field="material">
<div class="text-truncate" style="max-width: 150px;" title="<?php echo htmlspecialchars($v['material']); ?>">
<?php echo htmlspecialchars($v['material'] ?: '-'); ?>
</div>
</td>
<td class="editable" data-id="<?php echo $v['id']; ?>" data-field="angulo_video">
<div class="text-truncate" style="max-width: 150px;" title="<?php echo htmlspecialchars($v['angulo_video']); ?>">
<?php echo htmlspecialchars($v['angulo_video'] ?: '-'); ?>
</div>
</td>
<td class="text-center">
<?php if ($v['link_inspiracion_landing']): ?>
<a href="<?php echo $v['link_inspiracion_landing']; ?>" target="_blank" class="link-icon"><i class="fas fa-external-link-alt"></i></a>
<?php else: ?>
<span class="text-muted">-</span>
<?php endif; ?>
</td>
<td class="text-center">
<?php if ($v['link_inspiracion_video']): ?>
<a href="<?php echo $v['link_inspiracion_video']; ?>" target="_blank" class="link-icon text-danger"><i class="fab fa-youtube"></i></a>
<?php else: ?>
<span class="text-muted">-</span>
<?php endif; ?>
</td>
<td class="text-center">
<?php if ($v['link_video']): ?>
<a href="<?php echo $v['link_video']; ?>" target="_blank" class="link-icon text-success"><i class="fas fa-play-circle"></i></a>
<?php else: ?>
<span class="text-muted">-</span>
<?php endif; ?>
</td>
<td class="text-center">
<?php if ($v['link_landing']): ?>
<a href="<?php echo $v['link_landing']; ?>" target="_blank" class="link-icon text-info"><i class="fas fa-globe"></i></a>
<?php else: ?>
<span class="text-muted">-</span>
<?php endif; ?>
</td>
<td class="text-center">
<?php if ($v['link_flyer']): ?>
<a href="<?php echo $v['link_flyer']; ?>" target="_blank" class="link-icon text-warning"><i class="fas fa-file-image"></i></a>
<?php else: ?>
<span class="text-muted">-</span>
<?php endif; ?>
</td>
<td class="text-center editable" data-id="<?php echo $v['id']; ?>" data-field="estado">
<span class="badge status-badge <?php
echo $v['estado'] == 'Pendiente' ? 'bg-warning text-dark' :
($v['estado'] == 'En Proceso' ? 'bg-info' :
($v['estado'] == 'Terminado' ? 'bg-primary' : 'bg-success'));
?>">
<?php echo $v['estado']; ?>
</span>
</td>
<td class="text-center">
<button class="btn btn-sm btn-outline-primary" onclick="gestionarVideo(<?php echo htmlspecialchars(json_encode($v)); ?>)">
<i class="fas fa-edit"></i>
</button>
</td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
</tbody>
</table>
</div>
<?php else: ?>
<?php foreach ($videos as $v): ?>
<div class="col-md-4 mb-4">
<div class="card h-100 shadow-sm">
<div class="position-relative">
<?php if ($v['foto_producto']): ?>
<img src="<?php echo $v['foto_producto']; ?>" class="card-img-top" alt="Producto" style="height: 200px; object-fit: cover;">
<?php else: ?>
<div class="bg-light d-flex align-items-center justify-content-center" style="height: 200px;">
<i class="fas fa-image fa-3x text-muted"></i>
</div>
<?php endif; ?>
<span class="position-absolute top-0 end-0 m-2 badge <?php
echo $v['estado'] == 'Pendiente' ? 'bg-warning' :
($v['estado'] == 'En Proceso' ? 'bg-info' :
($v['estado'] == 'Terminado' ? 'bg-primary' : 'bg-success'));
?>">
<?php echo $v['estado']; ?>
</span>
</div>
<div class="card-body">
<h5 class="card-title"><?php echo htmlspecialchars($v['nombre_producto'] ?: 'Producto General'); ?></h5>
<p class="card-text text-muted small">
<?php echo nl2br(htmlspecialchars(substr($v['instrucciones'], 0, 100))); ?>...
</p>
<div class="d-flex justify-content-between align-items-center mt-3">
<small class="text-muted"><i class="far fa-calendar-alt"></i> <?php echo date('d/m/Y', strtotime($v['fecha_creacion'])); ?></small>
<?php if ($v['link_video']): ?>
<a href="<?php echo $v['link_video']; ?>" target="_blank" class="btn btn-sm btn-success">
<i class="fas fa-play"></i> Ver Video
</a>
<?php endif; ?>
</div>
</div>
<div class="card-footer bg-white border-top-0">
<button class="btn btn-outline-primary btn-sm w-100" onclick="verDetalles(<?php echo $v['id']; ?>)">
<i class="fas fa-edit"></i> Gestionar
</button>
</div>
</div>
</div>
<?php endforeach; ?>
<?php endif; ?>
</div>
</div>
<!-- Modal Nuevo Video -->
@ -93,8 +206,16 @@ $videos = $stmt_videos->fetchAll(PDO::FETCH_ASSOC);
</div>
<div class="modal-body">
<div class="row g-3">
<div class="col-md-6">
<label class="form-label">Producto Relacionado</label>
<div class="col-md-2">
<label class="form-label">Orden</label>
<input type="number" name="orden" class="form-control" value="1">
</div>
<div class="col-md-5">
<label class="form-label">Fecha Entrega</label>
<input type="date" name="fecha_entrega" class="form-control">
</div>
<div class="col-md-5">
<label class="form-label">Producto</label>
<select name="producto_id" class="form-select">
<option value="">Seleccionar producto...</option>
<?php foreach ($productos as $p): ?>
@ -103,12 +224,32 @@ $videos = $stmt_videos->fetchAll(PDO::FETCH_ASSOC);
</select>
</div>
<div class="col-md-6">
<label class="form-label">Foto de Referencia / Ángulo</label>
<label class="form-label">Imagen Referencia</label>
<input type="file" name="foto_producto" class="form-control" accept="image/*">
</div>
<div class="col-md-6">
<label class="form-label">Material</label>
<input type="text" name="material" class="form-control" placeholder="Ej: Acero, Plástico, etc.">
</div>
<div class="col-md-6">
<label class="form-label">Ángulo del Video</label>
<input type="text" name="angulo_video" class="form-control" placeholder="Ej: Cenital, 45 grados...">
</div>
<div class="col-md-6">
<label class="form-label">Link Inspiración Landing</label>
<input type="url" name="link_inspiracion_landing" class="form-control" placeholder="https://...">
</div>
<div class="col-md-6">
<label class="form-label">Link Inspiración Video</label>
<input type="url" name="link_inspiracion_video" class="form-control" placeholder="https://...">
</div>
<div class="col-md-12">
<label class="form-label">Link de Flyer</label>
<input type="url" name="link_flyer" class="form-control" placeholder="https://...">
</div>
<div class="col-12">
<label class="form-label">Instrucciones Detalladas</label>
<textarea name="instrucciones" class="form-control" rows="4" placeholder="Describe el ángulo, la música, el estilo del video, etc."></textarea>
<label class="form-label">Instrucciones Adicionales</label>
<textarea name="instrucciones" class="form-control" rows="3"></textarea>
</div>
</div>
</div>
@ -121,11 +262,176 @@ $videos = $stmt_videos->fetchAll(PDO::FETCH_ASSOC);
</div>
</div>
<!-- Modal Gestionar Video -->
<div class="modal fade" id="gestionarVideoModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<form action="save_marketing_video.php" method="POST">
<input type="hidden" name="action" value="update">
<input type="hidden" name="id" id="edit_id">
<div class="modal-header">
<h5 class="modal-title">Gestionar Pedido</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<div class="row g-3">
<div class="col-md-4">
<label class="form-label">Estado</label>
<select name="estado" id="edit_estado" class="form-select">
<option value="Pendiente">Pendiente</option>
<option value="En Proceso">En Proceso</option>
<option value="Terminado">Terminado</option>
<option value="Aprobado">Aprobado</option>
</select>
</div>
<div class="col-md-4">
<label class="form-label">Orden</label>
<input type="number" name="orden" id="edit_orden" class="form-control">
</div>
<div class="col-md-4">
<label class="form-label">Fecha Entrega</label>
<input type="date" name="fecha_entrega" id="edit_fecha_entrega" class="form-control">
</div>
<div class="col-md-6">
<label class="form-label">Material</label>
<input type="text" name="material" id="edit_material" class="form-control">
</div>
<div class="col-md-6">
<label class="form-label">Ángulo del Video</label>
<input type="text" name="angulo_video" id="edit_angulo_video" class="form-control">
</div>
<div class="col-md-6">
<label class="form-label">Link Inspiración Landing</label>
<input type="url" name="link_inspiracion_landing" id="edit_link_insp_landing" class="form-control">
</div>
<div class="col-md-6">
<label class="form-label">Link Inspiración Video</label>
<input type="url" name="link_inspiracion_video" id="edit_link_insp_video" class="form-control">
</div>
<div class="col-md-6">
<label class="form-label">Link Video Final</label>
<input type="url" name="link_video" id="edit_link_video" class="form-control">
</div>
<div class="col-md-6">
<label class="form-label">Link de la Landing</label>
<input type="url" name="link_landing" id="edit_link_landing" class="form-control">
</div>
<div class="col-md-12">
<label class="form-label">Link de Flyer</label>
<input type="url" name="link_flyer" id="edit_link_flyer" class="form-control">
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cerrar</button>
<button type="submit" class="btn btn-success">Guardar Cambios</button>
</div>
</form>
</div>
</div>
</div>
<script>
function verDetalles(id) {
// Por ahora solo mostramos un mensaje, luego implementaremos la edición
alert("Funcionalidad de edición para el ID " + id + " en desarrollo.");
function gestionarVideo(video) {
document.getElementById('edit_id').value = video.id;
document.getElementById('edit_estado').value = video.estado;
document.getElementById('edit_orden').value = video.orden || 0;
document.getElementById('edit_fecha_entrega').value = video.fecha_entrega || '';
document.getElementById('edit_material').value = video.material || '';
document.getElementById('edit_angulo_video').value = video.angulo_video || '';
document.getElementById('edit_link_insp_landing').value = video.link_inspiracion_landing || '';
document.getElementById('edit_link_insp_video').value = video.link_inspiracion_video || '';
document.getElementById('edit_link_video').value = video.link_video || '';
document.getElementById('edit_link_landing').value = video.link_landing || '';
document.getElementById('edit_link_flyer').value = video.link_flyer || '';
var myModal = new bootstrap.Modal(document.getElementById('gestionarVideoModal'));
myModal.show();
}
document.addEventListener('DOMContentLoaded', function() {
const editableCells = document.querySelectorAll('.editable');
editableCells.forEach(cell => {
cell.addEventListener('dblclick', function() {
if (this.querySelector('input') || this.querySelector('select')) return;
const id = this.getAttribute('data-id');
const field = this.getAttribute('data-field');
const currentValue = this.innerText.trim() === '-' ? '' : this.innerText.trim();
let input;
if (field === 'estado') {
input = document.createElement('select');
input.className = 'form-select form-select-sm inline-edit-input';
const options = ['Pendiente', 'En Proceso', 'Terminado', 'Aprobado'];
options.forEach(opt => {
const option = document.createElement('option');
option.value = opt;
option.text = opt;
if (opt === currentValue) option.selected = true;
input.appendChild(option);
});
} else {
input = document.createElement('input');
input.type = 'text';
input.className = 'form-control form-control-sm inline-edit-input';
input.value = currentValue;
}
const originalContent = this.innerHTML;
this.innerHTML = '';
this.appendChild(input);
input.focus();
const saveChange = () => {
const newValue = input.value;
if (newValue === currentValue) {
this.innerHTML = originalContent;
return;
}
fetch('update_marketing_video_field.php', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ id, field, value: newValue })
})
.then(response => response.json())
.then(data => {
if (data.success) {
if (field === 'estado') {
let badgeClass = 'bg-secondary';
if (newValue === 'Pendiente') badgeClass = 'bg-warning text-dark';
else if (newValue === 'En Proceso') badgeClass = 'bg-info';
else if (newValue === 'Terminado') badgeClass = 'bg-primary';
else if (newValue === 'Aprobado') badgeClass = 'bg-success';
this.innerHTML = `<span class="badge status-badge ${badgeClass}">${newValue}</span>`;
} else {
this.innerHTML = `<div class="text-truncate" style="max-width: 150px;" title="${newValue}">${newValue || '-'}</div>`;
}
} else {
alert('Error: ' + data.error);
this.innerHTML = originalContent;
}
})
.catch(error => {
console.error('Error:', error);
this.innerHTML = originalContent;
});
};
input.addEventListener('blur', saveChange);
input.addEventListener('keydown', function(e) {
if (e.key === 'Enter') {
input.blur();
} else if (e.key === 'Escape') {
cell.innerHTML = originalContent;
}
});
});
});
});
</script>
<?php include 'layout_footer.php'; ?>

29
save_marketing_asset.php Normal file
View File

@ -0,0 +1,29 @@
<?php
include 'db/config.php';
$db = db();
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$nombre = $_POST['nombre'] ?? '';
$categoria = $_POST['categoria'] ?? 'Otros';
if (isset($_FILES['archivo']) && $_FILES['archivo']['error'] == 0) {
$uploadDir = 'assets/uploads/marketing_assets/';
if (!is_dir($uploadDir)) {
mkdir($uploadDir, 0777, true);
}
$fileName = time() . '_' . basename($_FILES['archivo']['name']);
$targetPath = $uploadDir . $fileName;
if (move_uploaded_file($_FILES['archivo']['tmp_name'], $targetPath)) {
$stmt = $db->prepare("INSERT INTO marketing_assets (nombre, categoria, archivo_path) VALUES (?, ?, ?)");
$stmt->execute([$nombre, $categoria, $targetPath]);
header("Location: marketing_assets.php?success=1");
exit;
}
}
}
header("Location: marketing_assets.php?error=1");
exit;

View File

@ -9,29 +9,110 @@ if (!isset($_SESSION['user_id'])) {
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$db = db();
$producto_id = !empty($_POST['producto_id']) ? $_POST['producto_id'] : null;
$instrucciones = $_POST['instrucciones'] ?? '';
$foto_path = null;
$action = $_POST['action'] ?? 'create';
// Manejo de la subida de foto
if (isset($_FILES['foto_producto']) && $_FILES['foto_producto']['error'] == 0) {
$target_dir = "assets/uploads/marketing_images/";
$file_extension = pathinfo($_FILES["foto_producto"]["name"], PATHINFO_EXTENSION);
$file_name = uniqid() . '.' . $file_extension;
$target_file = $target_dir . $file_name;
if ($action == 'update') {
// Lógica para actualizar (Editora o Tú)
$id = $_POST['id'];
$estado = $_POST['estado'];
$link_video = $_POST['link_video'] ?? '';
$link_landing = $_POST['link_landing'] ?? '';
$link_flyer = $_POST['link_flyer'] ?? '';
$material = $_POST['material'] ?? '';
$fecha_entrega = !empty($_POST['fecha_entrega']) ? $_POST['fecha_entrega'] : null;
$orden = !empty($_POST['orden']) ? $_POST['orden'] : 0;
$angulo_video = $_POST['angulo_video'] ?? '';
$link_inspiracion_landing = $_POST['link_inspiracion_landing'] ?? '';
$link_inspiracion_video = $_POST['link_inspiracion_video'] ?? '';
if (move_uploaded_file($_FILES["foto_producto"]["tmp_name"], $target_file)) {
$foto_path = $target_file;
try {
$stmt = $db->prepare("UPDATE marketing_videos SET
estado = ?,
link_video = ?,
link_landing = ?,
link_flyer = ?,
material = ?,
fecha_entrega = ?,
orden = ?,
angulo_video = ?,
link_inspiracion_landing = ?,
link_inspiracion_video = ?
WHERE id = ?");
$stmt->execute([
$estado,
$link_video,
$link_landing,
$link_flyer,
$material,
$fecha_entrega,
$orden,
$angulo_video,
$link_inspiracion_landing,
$link_inspiracion_video,
$id
]);
header('Location: marketing_produccion.php?success=updated');
} catch (PDOException $e) {
echo "Error: " . $e->getMessage();
}
}
try {
$stmt = $db->prepare("INSERT INTO marketing_videos (producto_id, foto_producto, instrucciones, estado) VALUES (?, ?, ?, 'Pendiente')");
$stmt->execute([$producto_id, $foto_path, $instrucciones]);
} else {
// Lógica para crear (Tú)
$producto_id = !empty($_POST['producto_id']) ? $_POST['producto_id'] : null;
$instrucciones = $_POST['instrucciones'] ?? '';
$fecha_entrega = !empty($_POST['fecha_entrega']) ? $_POST['fecha_entrega'] : null;
$orden = !empty($_POST['orden']) ? $_POST['orden'] : 0;
$angulo_video = $_POST['angulo_video'] ?? '';
$link_inspiracion_landing = $_POST['link_inspiracion_landing'] ?? '';
$link_inspiracion_video = $_POST['link_inspiracion_video'] ?? '';
$link_flyer = $_POST['link_flyer'] ?? '';
$material = $_POST['material'] ?? '';
header('Location: marketing_produccion.php?success=1');
} catch (PDOException $e) {
echo "Error: " . $e->getMessage();
$foto_path = null;
if (isset($_FILES['foto_producto']) && $_FILES['foto_producto']['error'] == 0) {
$target_dir = "assets/uploads/marketing_images/";
if (!is_dir($target_dir)) {
mkdir($target_dir, 0777, true);
}
$file_extension = pathinfo($_FILES["foto_producto"]["name"], PATHINFO_EXTENSION);
$file_name = uniqid() . '.' . $file_extension;
$target_file = $target_dir . $file_name;
if (move_uploaded_file($_FILES["foto_producto"]["tmp_name"], $target_file)) {
$foto_path = $target_file;
}
}
try {
$stmt = $db->prepare("INSERT INTO marketing_videos (
producto_id,
foto_producto,
material,
instrucciones,
estado,
fecha_entrega,
orden,
angulo_video,
link_inspiracion_landing,
link_inspiracion_video,
link_flyer
) VALUES (?, ?, ?, ?, 'Pendiente', ?, ?, ?, ?, ?, ?)");
$stmt->execute([
$producto_id,
$foto_path,
$material,
$instrucciones,
$fecha_entrega,
$orden,
$angulo_video,
$link_inspiracion_landing,
$link_inspiracion_video,
$link_flyer
]);
header('Location: marketing_produccion.php?success=created');
} catch (PDOException $e) {
echo "Error: " . $e->getMessage();
}
}
}
?>

View File

@ -0,0 +1,46 @@
<?php
session_start();
require_once 'db/config.php';
if (!isset($_SESSION['user_id'])) {
http_response_code(403);
echo json_encode(['error' => 'Acceso no autorizado.']);
exit;
}
$data = json_decode(file_get_contents('php://input'), true);
if (!$data || !isset($data['id']) || !isset($data['field']) || !isset($data['value'])) {
http_response_code(400);
echo json_encode(['error' => 'Datos incompletos.']);
exit;
}
$video_id = $data['id'];
$field = $data['field'];
$value = $data['value'];
// Whitelist allowed fields for security
$allowed_fields = ['material', 'estado', 'angulo_video'];
if (!in_array($field, $allowed_fields)) {
http_response_code(400);
echo json_encode(['error' => 'Campo no permitido.']);
exit;
}
try {
$pdo = db();
$sql = "UPDATE marketing_videos SET $field = ? WHERE id = ?";
$stmt = $pdo->prepare($sql);
$stmt->execute([$value, $video_id]);
echo json_encode([
'success' => true,
'message' => 'Campo actualizado correctamente.'
]);
} catch (PDOException $e) {
http_response_code(500);
echo json_encode(['error' => 'Error al actualizar la base de datos: ' . $e->getMessage()]);
}
?>