Files
stl-repo/static/upload.html
Consultoria AS 5aa8d7512a feat: branding PrintForge + logo + dominio 3d.consultoria-as.com
- Nombre de app: PrintForge
- Logo generado: icono + version completa
- Integracion en navbar y favicon de todas las paginas
- QR code apunta a https://3d.consultoria-as.com
- README actualizado con URL de produccion
2026-04-28 04:45:32 +00:00

269 lines
19 KiB
HTML

<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Subir Modelo - PrintForge</title>
<link rel="icon" type="image/png" href="/static/logo-icon.png">
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="/static/css/style.css">
<script>
tailwind.config = {
theme: {
extend: {
colors: {
slate: { 850: '#172033', 950: '#020617' }
}
}
}
}
</script>
</head>
<body class="bg-slate-950 text-slate-100 min-h-screen">
<!-- Navbar -->
<nav class="glass sticky top-0 z-50 border-b border-white/5">
<div class="max-w-7xl mx-auto px-6 py-4 flex items-center justify-between">
<a href="/" class="flex items-center gap-3 group">
<img src="/static/logo-icon.png" alt="PrintForge" class="w-10 h-10 rounded-xl shadow-lg group-hover:scale-110 transition-transform">
<div>
<h1 class="text-xl font-bold bg-gradient-to-r from-cyan-400 to-blue-400 bg-clip-text text-transparent">PrintForge</h1>
<p class="text-xs text-slate-400 -mt-0.5">Forja tus ideas en 3D</p>
</div>
</a>
<button id="theme-toggle" class="p-2.5 rounded-xl bg-slate-800 hover:bg-slate-700 border border-white/10 text-slate-400 hover:text-yellow-400 transition-colors mr-2" title="Cambiar tema">
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z"></path></svg>
</button>
<a href="/" class="px-5 py-2.5 rounded-xl bg-slate-800 hover:bg-slate-700 border border-white/10 text-sm font-medium transition-colors">
Volver a Galeria
</a>
</div>
</nav>
<!-- Main -->
<main class="max-w-3xl mx-auto px-6 py-10">
<div class="mb-8">
<h2 class="text-3xl font-bold mb-2">Subir nuevo modelo</h2>
<p class="text-slate-400">Selecciona uno o mas archivos STL/3MF, importa desde URL o sube un ZIP.</p>
</div>
<!-- Tabs -->
<div class="flex gap-2 mb-6">
<button id="tab-upload" class="flex-1 px-4 py-3 rounded-xl bg-cyan-500/20 text-cyan-400 border border-cyan-500/30 font-medium text-sm transition-all">
📁 Archivos
</button>
<button id="tab-url" class="flex-1 px-4 py-3 rounded-xl bg-slate-800 border border-white/10 text-slate-400 font-medium text-sm transition-all hover:bg-slate-700">
🌐 URL
</button>
<button id="tab-zip" class="flex-1 px-4 py-3 rounded-xl bg-slate-800 border border-white/10 text-slate-400 font-medium text-sm transition-all hover:bg-slate-700">
🗜️ ZIP
</button>
</div>
<!-- Panel: Upload -->
<div id="panel-upload">
<!-- 3D Files Drop Zone -->
<div id="drop-zone" class="border-2 border-dashed border-slate-700 rounded-2xl p-10 text-center cursor-pointer transition-all hover:border-cyan-500/50 hover:bg-slate-900/40 mb-4 group">
<div class="w-16 h-16 rounded-2xl bg-slate-900 flex items-center justify-center mx-auto mb-3 group-hover:scale-110 transition-transform group-hover:bg-cyan-500/10">
<svg class="w-8 h-8 text-slate-400 group-hover:text-cyan-400 transition-colors" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M20 7l-8-4-8 4m16 0l-8 4m8-4v10l-8 4m0-10L4 7m8 4v10M4 7v10l8 4"></path></svg>
</div>
<h3 class="text-base font-semibold mb-1">Archivos 3D (STL / 3MF)</h3>
<p class="text-sm text-slate-500 mb-2">Arrastra uno o mas archivos aqui</p>
<p id="file-name" class="text-cyan-400 font-medium text-sm min-h-[20px]"></p>
<input type="file" id="file-input" accept=".stl,.3mf" multiple class="hidden">
</div>
<!-- Parts list -->
<div id="parts-list" class="space-y-2 mb-6"></div>
<!-- Images Drop Zone -->
<div id="images-drop-zone" class="border-2 border-dashed border-slate-700 rounded-2xl p-8 text-center cursor-pointer transition-all hover:border-fuchsia-500/50 hover:bg-slate-900/40 mb-8 group">
<div class="w-14 h-14 rounded-2xl bg-slate-900 flex items-center justify-center mx-auto mb-3 group-hover:scale-110 transition-transform group-hover:bg-fuchsia-500/10">
<svg class="w-7 h-7 text-slate-400 group-hover:text-fuchsia-400 transition-colors" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z"></path></svg>
</div>
<h3 class="text-sm font-semibold mb-1">Imagenes de referencia</h3>
<p class="text-xs text-slate-500 mb-2">Opcional - JPG o PNG</p>
<p id="images-name" class="text-fuchsia-400 font-medium text-sm min-h-[20px]"></p>
<input type="file" id="images-input" accept=".jpg,.jpeg,.png" multiple class="hidden">
</div>
<!-- Form -->
<form id="upload-form" class="glass rounded-2xl p-8 space-y-5">
<div>
<label class="block text-sm font-medium text-slate-300 mb-1.5">Titulo <span class="text-cyan-500">*</span></label>
<input type="text" id="title" required placeholder="Ej: Soporte para telefono" class="w-full px-4 py-3 rounded-xl bg-slate-900/60 border border-white/10 focus:border-cyan-500 focus:outline-none focus:ring-2 focus:ring-cyan-500/20 transition-all placeholder:text-slate-600">
</div>
<div>
<label class="block text-sm font-medium text-slate-300 mb-1.5">Descripcion</label>
<textarea id="description" rows="3" placeholder="Describe el modelo, materiales recomendados, etc." class="w-full px-4 py-3 rounded-xl bg-slate-900/60 border border-white/10 focus:border-cyan-500 focus:outline-none focus:ring-2 focus:ring-cyan-500/20 transition-all placeholder:text-slate-600 resize-none"></textarea>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-5">
<div>
<label class="block text-sm font-medium text-slate-300 mb-1.5">Autor</label>
<input type="text" id="author" placeholder="Tu nombre o alias" class="w-full px-4 py-3 rounded-xl bg-slate-900/60 border border-white/10 focus:border-cyan-500 focus:outline-none focus:ring-2 focus:ring-cyan-500/20 transition-all placeholder:text-slate-600">
</div>
<div>
<label class="block text-sm font-medium text-slate-300 mb-1.5">Licencia</label>
<select id="license-select" class="w-full px-4 py-3 rounded-xl bg-slate-900/60 border border-white/10 focus:border-cyan-500 focus:outline-none focus:ring-2 focus:ring-cyan-500/20 transition-all cursor-pointer text-slate-300 mb-2">
<option value="">Seleccionar licencia...</option>
<option value="CC0 1.0 Universal">CC0 - Dominio Publico</option>
<option value="CC-BY 4.0">CC-BY 4.0 - Atribucion</option>
<option value="CC-BY-SA 4.0">CC-BY-SA 4.0 - Compartir Igual</option>
<option value="CC-BY-NC 4.0">CC-BY-NC 4.0 - No Comercial</option>
<option value="CC-BY-NC-SA 4.0">CC-BY-NC-SA 4.0 - NC + SA</option>
<option value="CC-BY-ND 4.0">CC-BY-ND 4.0 - Sin Derivadas</option>
<option value="GPL-3.0">GPL-3.0</option>
<option value="MIT">MIT</option>
<option value="custom">Otra (personalizada)</option>
</select>
<input type="text" id="license" placeholder="Ej: Mi licencia personal" class="w-full px-4 py-3 rounded-xl bg-slate-900/60 border border-white/10 focus:border-cyan-500 focus:outline-none focus:ring-2 focus:ring-cyan-500/20 transition-all placeholder:text-slate-600 hidden">
</div>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-5">
<div>
<label class="block text-sm font-medium text-slate-300 mb-1.5">Categoria</label>
<select id="category" class="w-full px-4 py-3 rounded-xl bg-slate-900/60 border border-white/10 focus:border-cyan-500 focus:outline-none focus:ring-2 focus:ring-cyan-500/20 transition-all cursor-pointer text-slate-300">
<option value="">Sin categoria</option>
<option value="Arte">Arte</option>
<option value="Herramientas">Herramientas</option>
<option value="Juguetes">Juguetes</option>
<option value="Piezas">Piezas</option>
<option value="Decoracion">Decoracion</option>
<option value="Otros">Otros</option>
</select>
</div>
<div class="relative">
<label class="block text-sm font-medium text-slate-300 mb-1.5">Tags</label>
<input type="text" id="tags" placeholder="robot, articulado, util" class="w-full px-4 py-3 rounded-xl bg-slate-900/60 border border-white/10 focus:border-cyan-500 focus:outline-none focus:ring-2 focus:ring-cyan-500/20 transition-all placeholder:text-slate-600">
<div id="tags-suggestions" class="absolute left-0 right-0 top-full mt-1 glass rounded-xl border border-white/10 overflow-hidden z-20 hidden"></div>
<p class="text-xs text-slate-500 mt-1">Separados por comas. Escribe para ver sugerencias.</p>
</div>
</div>
<div class="pt-4">
<button type="submit" id="submit-btn" class="w-full md:w-auto px-8 py-3.5 rounded-xl bg-gradient-to-r from-cyan-500 to-blue-600 hover:from-cyan-400 hover:to-blue-500 text-white font-bold shadow-lg shadow-cyan-500/20 transition-all hover:scale-[1.02] disabled:opacity-50 disabled:cursor-not-allowed flex items-center justify-center gap-2">
<svg id="btn-icon" class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-8l-4-4m0 0L8 8m4-4v12"></path></svg>
<span id="btn-text">Subir Modelo</span>
</button>
</div>
</form>
</div>
<!-- Panel: URL -->
<div id="panel-url" class="hidden">
<form id="url-form" class="glass rounded-2xl p-8 space-y-5">
<div>
<label class="block text-sm font-medium text-slate-300 mb-1.5">URL del archivo <span class="text-cyan-500">*</span></label>
<input type="url" id="url-input" required placeholder="https://ejemplo.com/modelo.stl" class="w-full px-4 py-3 rounded-xl bg-slate-900/60 border border-white/10 focus:border-cyan-500 focus:outline-none focus:ring-2 focus:ring-cyan-500/20 transition-all placeholder:text-slate-600">
<p class="text-xs text-slate-500 mt-1">Soporta archivos .stl y .3mf directos. Maximo 50MB.</p>
</div>
<div>
<label class="block text-sm font-medium text-slate-300 mb-1.5">Titulo <span class="text-cyan-500">*</span></label>
<input type="text" id="url-title" required placeholder="Ej: Soporte para telefono" class="w-full px-4 py-3 rounded-xl bg-slate-900/60 border border-white/10 focus:border-cyan-500 focus:outline-none focus:ring-2 focus:ring-cyan-500/20 transition-all placeholder:text-slate-600">
</div>
<div>
<label class="block text-sm font-medium text-slate-300 mb-1.5">Descripcion</label>
<textarea id="url-description" rows="3" class="w-full px-4 py-3 rounded-xl bg-slate-900/60 border border-white/10 focus:border-cyan-500 focus:outline-none focus:ring-2 focus:ring-cyan-500/20 transition-all placeholder:text-slate-600 resize-none"></textarea>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-5">
<div>
<label class="block text-sm font-medium text-slate-300 mb-1.5">Autor</label>
<input type="text" id="url-author" placeholder="Tu nombre o alias" class="w-full px-4 py-3 rounded-xl bg-slate-900/60 border border-white/10 focus:border-cyan-500 focus:outline-none focus:ring-2 focus:ring-cyan-500/20 transition-all placeholder:text-slate-600">
</div>
<div>
<label class="block text-sm font-medium text-slate-300 mb-1.5">Licencia</label>
<input type="text" id="url-license" placeholder="Ej: CC-BY-SA 4.0" class="w-full px-4 py-3 rounded-xl bg-slate-900/60 border border-white/10 focus:border-cyan-500 focus:outline-none focus:ring-2 focus:ring-cyan-500/20 transition-all placeholder:text-slate-600">
</div>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-5">
<div>
<label class="block text-sm font-medium text-slate-300 mb-1.5">Categoria</label>
<select id="url-category" class="w-full px-4 py-3 rounded-xl bg-slate-900/60 border border-white/10 focus:border-cyan-500 focus:outline-none focus:ring-2 focus:ring-cyan-500/20 transition-all cursor-pointer text-slate-300">
<option value="">Sin categoria</option>
<option value="Arte">Arte</option>
<option value="Herramientas">Herramientas</option>
<option value="Juguetes">Juguetes</option>
<option value="Piezas">Piezas</option>
<option value="Decoracion">Decoracion</option>
<option value="Otros">Otros</option>
</select>
</div>
<div>
<label class="block text-sm font-medium text-slate-300 mb-1.5">Tags</label>
<input type="text" id="url-tags" placeholder="robot, articulado, util" class="w-full px-4 py-3 rounded-xl bg-slate-900/60 border border-white/10 focus:border-cyan-500 focus:outline-none focus:ring-2 focus:ring-cyan-500/20 transition-all placeholder:text-slate-600">
</div>
</div>
<div class="pt-4">
<button type="submit" class="w-full md:w-auto px-8 py-3.5 rounded-xl bg-gradient-to-r from-cyan-500 to-blue-600 hover:from-cyan-400 hover:to-blue-500 text-white font-bold shadow-lg shadow-cyan-500/20 transition-all hover:scale-[1.02] flex items-center justify-center gap-2">
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-8l-4-4m0 0L8 8m4-4v12"></path></svg>
Importar desde URL
</button>
</div>
</form>
</div>
<!-- Panel: ZIP -->
<div id="panel-zip" class="hidden">
<div id="zip-drop-zone" class="border-2 border-dashed border-slate-700 rounded-2xl p-10 text-center cursor-pointer transition-all hover:border-cyan-500/50 hover:bg-slate-900/40 mb-6 group">
<div class="w-16 h-16 rounded-2xl bg-slate-900 flex items-center justify-center mx-auto mb-3 group-hover:scale-110 transition-transform group-hover:bg-cyan-500/10">
<svg class="w-8 h-8 text-slate-400 group-hover:text-cyan-400 transition-colors" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M5 8h14M5 8a2 2 0 110-4h14a2 2 0 110 4M5 8v10a2 2 0 002 2h10a2 2 0 002-2V8m-9 4h4"></path></svg>
</div>
<h3 class="text-base font-semibold mb-1">Archivo ZIP</h3>
<p class="text-sm text-slate-500 mb-2">Arrastra un ZIP con archivos STL/3MF</p>
<p id="zip-name" class="text-cyan-400 font-medium text-sm min-h-[20px]"></p>
<input type="file" id="zip-input" accept=".zip" class="hidden">
</div>
<form id="zip-form" class="glass rounded-2xl p-8 space-y-5">
<div>
<label class="block text-sm font-medium text-slate-300 mb-1.5">Descripcion (aplicada a todos)</label>
<textarea id="zip-description" rows="2" class="w-full px-4 py-3 rounded-xl bg-slate-900/60 border border-white/10 focus:border-cyan-500 focus:outline-none focus:ring-2 focus:ring-cyan-500/20 transition-all placeholder:text-slate-600 resize-none"></textarea>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-5">
<div>
<label class="block text-sm font-medium text-slate-300 mb-1.5">Autor</label>
<input type="text" id="zip-author" placeholder="Tu nombre o alias" class="w-full px-4 py-3 rounded-xl bg-slate-900/60 border border-white/10 focus:border-cyan-500 focus:outline-none focus:ring-2 focus:ring-cyan-500/20 transition-all placeholder:text-slate-600">
</div>
<div>
<label class="block text-sm font-medium text-slate-300 mb-1.5">Licencia</label>
<input type="text" id="zip-license" placeholder="Ej: CC-BY-SA 4.0" class="w-full px-4 py-3 rounded-xl bg-slate-900/60 border border-white/10 focus:border-cyan-500 focus:outline-none focus:ring-2 focus:ring-cyan-500/20 transition-all placeholder:text-slate-600">
</div>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-5">
<div>
<label class="block text-sm font-medium text-slate-300 mb-1.5">Categoria</label>
<select id="zip-category" class="w-full px-4 py-3 rounded-xl bg-slate-900/60 border border-white/10 focus:border-cyan-500 focus:outline-none focus:ring-2 focus:ring-cyan-500/20 transition-all cursor-pointer text-slate-300">
<option value="">Sin categoria</option>
<option value="Arte">Arte</option>
<option value="Herramientas">Herramientas</option>
<option value="Juguetes">Juguetes</option>
<option value="Piezas">Piezas</option>
<option value="Decoracion">Decoracion</option>
<option value="Otros">Otros</option>
</select>
</div>
<div>
<label class="block text-sm font-medium text-slate-300 mb-1.5">Tags (aplicados a todos)</label>
<input type="text" id="zip-tags" placeholder="robot, articulado, util" class="w-full px-4 py-3 rounded-xl bg-slate-900/60 border border-white/10 focus:border-cyan-500 focus:outline-none focus:ring-2 focus:ring-cyan-500/20 transition-all placeholder:text-slate-600">
</div>
</div>
<div class="pt-4">
<button type="submit" class="w-full md:w-auto px-8 py-3.5 rounded-xl bg-gradient-to-r from-cyan-500 to-blue-600 hover:from-cyan-400 hover:to-blue-500 text-white font-bold shadow-lg shadow-cyan-500/20 transition-all hover:scale-[1.02] flex items-center justify-center gap-2">
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 8h14M5 8a2 2 0 110-4h14a2 2 0 110 4M5 8v10a2 2 0 002 2h10a2 2 0 002-2V8m-9 4h4"></path></svg>
Procesar ZIP
</button>
</div>
</form>
</div>
</main>
<div id="toast-container"></div>
<script src="/static/js/theme.js"></script>
<script src="/static/js/api.js"></script>
<script src="/static/js/upload.js"></script>
</body>
</html>