Usuario vendedor y pestaña descargas
This commit is contained in:
+3
-3
@@ -576,7 +576,7 @@ app.post('/api/usuarios', requireUserManagement, async (req, res) => {
|
|||||||
if (contraseña.length < 6) {
|
if (contraseña.length < 6) {
|
||||||
return res.status(400).json({ error: 'La contraseña debe tener al menos 6 caracteres' });
|
return res.status(400).json({ error: 'La contraseña debe tener al menos 6 caracteres' });
|
||||||
}
|
}
|
||||||
if (!['admin', 'editor'].includes(rol)) {
|
if (!['admin', 'editor', 'vendedor'].includes(rol)) {
|
||||||
return res.status(400).json({ error: 'Rol inválido' });
|
return res.status(400).json({ error: 'Rol inválido' });
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -588,7 +588,7 @@ app.post('/api/usuarios', requireUserManagement, async (req, res) => {
|
|||||||
return res.status(409).json({ error: 'Ya existe un usuario con ese nombre' });
|
return res.status(409).json({ error: 'Ya existe un usuario con ese nombre' });
|
||||||
}
|
}
|
||||||
|
|
||||||
// Admin siempre tiene todos los permisos; editor recibe la lista enviada
|
// Admin siempre tiene todos los permisos; editor/vendedor reciben la lista enviada
|
||||||
const permisosFinal = rol === 'admin'
|
const permisosFinal = rol === 'admin'
|
||||||
? []
|
? []
|
||||||
: (Array.isArray(permisos) ? permisos : []);
|
: (Array.isArray(permisos) ? permisos : []);
|
||||||
@@ -606,7 +606,7 @@ app.put('/api/usuarios/:usuario', requireUserManagement, async (req, res) => {
|
|||||||
const targetUsuario = req.params.usuario;
|
const targetUsuario = req.params.usuario;
|
||||||
const { contraseña, rol, permisos } = req.body || {};
|
const { contraseña, rol, permisos } = req.body || {};
|
||||||
|
|
||||||
if (rol && !['admin', 'editor'].includes(rol)) {
|
if (rol && !['admin', 'editor', 'vendedor'].includes(rol)) {
|
||||||
return res.status(400).json({ error: 'Rol inválido' });
|
return res.status(400).json({ error: 'Rol inválido' });
|
||||||
}
|
}
|
||||||
if (contraseña && contraseña.length < 6) {
|
if (contraseña && contraseña.length < 6) {
|
||||||
|
|||||||
@@ -8,9 +8,9 @@
|
|||||||
{
|
{
|
||||||
"usuario": "juan",
|
"usuario": "juan",
|
||||||
"contraseña": "123456",
|
"contraseña": "123456",
|
||||||
"rol": "editor",
|
"rol": "vendedor",
|
||||||
"permisos": [
|
"permisos": [
|
||||||
"productos"
|
"descargas"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
+1
-1
@@ -3,7 +3,7 @@
|
|||||||
"id": "AF100-124",
|
"id": "AF100-124",
|
||||||
"ref": "AF100-124",
|
"ref": "AF100-124",
|
||||||
"cat": "bolsos",
|
"cat": "bolsos",
|
||||||
"img": "bolsos/AF100-124.webp",
|
"img": "agotados/AF100-124.webp",
|
||||||
"nombre": "Bolso de cuero negro estilo clásico",
|
"nombre": "Bolso de cuero negro estilo clásico",
|
||||||
"precio": 50000
|
"precio": 50000
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -4,5 +4,29 @@
|
|||||||
"usuario": "admin",
|
"usuario": "admin",
|
||||||
"rol": "admin",
|
"rol": "admin",
|
||||||
"createdAt": 1780718070269
|
"createdAt": 1780718070269
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"token": "18342f8390074dea906ffebf0f0a5e34feb6a27c9caf2c7c721542dd961d5d59",
|
||||||
|
"usuario": "admin",
|
||||||
|
"rol": "admin",
|
||||||
|
"createdAt": 1780719045054
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"token": "7e95e1adfdc6f90a52122d72e6e05d24bcafd4c9727be52976ea312a636ab2f5",
|
||||||
|
"usuario": "vendetest",
|
||||||
|
"rol": "vendedor",
|
||||||
|
"createdAt": 1780719045099
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"token": "a9b4be06e4e40fe83595d388a8c08b9270df7557e2a2b63b793552609b2d2d71",
|
||||||
|
"usuario": "vendetest",
|
||||||
|
"rol": "vendedor",
|
||||||
|
"createdAt": 1780719061095
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"token": "4cb3d9aa79e1c83e87863a32d4cbbc9a2eafadaa08ba110964250121939b8d3a",
|
||||||
|
"usuario": "admin",
|
||||||
|
"rol": "admin",
|
||||||
|
"createdAt": 1780719205299
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1025,6 +1025,11 @@ select {
|
|||||||
color: #0e7490;
|
color: #0e7490;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.rol-vendedor {
|
||||||
|
background: linear-gradient(135deg, rgba(252, 211, 77, 0.22) 0%, rgba(251, 146, 60, 0.22) 100%);
|
||||||
|
color: #b45309;
|
||||||
|
}
|
||||||
|
|
||||||
.you-badge {
|
.you-badge {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
margin-left: 6px;
|
margin-left: 6px;
|
||||||
@@ -1194,6 +1199,89 @@ select {
|
|||||||
75% { transform: translateX(6px); }
|
75% { transform: translateX(6px); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ════════════════════════════════
|
||||||
|
SUBTABS (vista Descargas)
|
||||||
|
════════════════════════════════ */
|
||||||
|
.subtabs {
|
||||||
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
|
padding: 6px;
|
||||||
|
background: var(--surface);
|
||||||
|
border: 1px solid var(--line);
|
||||||
|
border-radius: var(--radius-lg);
|
||||||
|
margin-bottom: 18px;
|
||||||
|
width: fit-content;
|
||||||
|
max-width: 100%;
|
||||||
|
overflow-x: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.subtab {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
padding: 9px 18px;
|
||||||
|
border: 1px solid transparent;
|
||||||
|
background: transparent;
|
||||||
|
color: var(--ink-mute);
|
||||||
|
font: inherit;
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 0.88rem;
|
||||||
|
border-radius: calc(var(--radius-lg) - 6px);
|
||||||
|
cursor: pointer;
|
||||||
|
transition: color .18s ease, background .18s ease, border-color .18s ease;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.subtab:hover:not(.active) {
|
||||||
|
color: var(--ink);
|
||||||
|
background: rgba(255,255,255,0.45);
|
||||||
|
}
|
||||||
|
|
||||||
|
.subtab.active {
|
||||||
|
background: linear-gradient(135deg, var(--violet), var(--pink));
|
||||||
|
color: #fff;
|
||||||
|
border-color: var(--line-strong);
|
||||||
|
box-shadow: 0 4px 14px -6px rgba(167, 139, 250, 0.55);
|
||||||
|
}
|
||||||
|
|
||||||
|
.subtab-icon { font-size: 1rem; line-height: 1; }
|
||||||
|
.subtab-label { line-height: 1; }
|
||||||
|
|
||||||
|
.subtab-panel { display: none; }
|
||||||
|
.subtab-panel.active { display: block; }
|
||||||
|
|
||||||
|
.subtab-placeholder {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
text-align: center;
|
||||||
|
padding: 48px 24px;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.subtab-placeholder-icon {
|
||||||
|
font-size: 3.2rem;
|
||||||
|
line-height: 1;
|
||||||
|
opacity: 0.85;
|
||||||
|
filter: drop-shadow(0 6px 18px rgba(167, 139, 250, 0.35));
|
||||||
|
}
|
||||||
|
|
||||||
|
.subtab-placeholder h3 {
|
||||||
|
margin: 0;
|
||||||
|
font-family: var(--font-serif);
|
||||||
|
font-size: 1.35rem;
|
||||||
|
font-weight: 400;
|
||||||
|
color: var(--ink);
|
||||||
|
}
|
||||||
|
|
||||||
|
.subtab-placeholder p {
|
||||||
|
margin: 0;
|
||||||
|
color: var(--ink-mute);
|
||||||
|
max-width: 460px;
|
||||||
|
line-height: 1.55;
|
||||||
|
}
|
||||||
|
|
||||||
@media (prefers-reduced-motion: reduce) {
|
@media (prefers-reduced-motion: reduce) {
|
||||||
*, *::before, *::after {
|
*, *::before, *::after {
|
||||||
animation-duration: 0.01ms !important;
|
animation-duration: 0.01ms !important;
|
||||||
@@ -1202,6 +1290,12 @@ select {
|
|||||||
.mesh-blob { animation: none; }
|
.mesh-blob { animation: none; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media (max-width: 480px) {
|
||||||
|
.subtab { padding: 8px 12px; font-size: 0.82rem; }
|
||||||
|
.subtab-placeholder { padding: 32px 16px; }
|
||||||
|
.subtab-placeholder-icon { font-size: 2.6rem; }
|
||||||
|
}
|
||||||
|
|
||||||
/* ════════════════════════════════
|
/* ════════════════════════════════
|
||||||
RESPONSIVE — topbar wrap
|
RESPONSIVE — topbar wrap
|
||||||
════════════════════════════════ */
|
════════════════════════════════ */
|
||||||
|
|||||||
@@ -10,13 +10,15 @@
|
|||||||
const TABS = [
|
const TABS = [
|
||||||
{ id: 'productos', label: 'Productos', icon: '📦' },
|
{ id: 'productos', label: 'Productos', icon: '📦' },
|
||||||
{ id: 'agotados', label: 'Agotados', icon: '🚫' },
|
{ id: 'agotados', label: 'Agotados', icon: '🚫' },
|
||||||
|
{ id: 'descargas', label: 'Descargas', icon: '⬇️' },
|
||||||
{ id: 'categorias', label: 'Categorías', icon: '🗂️' },
|
{ id: 'categorias', label: 'Categorías', icon: '🗂️' },
|
||||||
{ id: 'usuarios', label: 'Usuarios', icon: '👥' }
|
{ id: 'usuarios', label: 'Usuarios', icon: '👥' }
|
||||||
];
|
];
|
||||||
|
|
||||||
const ROLES = {
|
const ROLES = {
|
||||||
admin: 'Administrador',
|
admin: 'Administrador',
|
||||||
editor: 'Editor'
|
editor: 'Editor',
|
||||||
|
vendedor: 'Vendedor'
|
||||||
};
|
};
|
||||||
|
|
||||||
// Iconos disponibles para categorías
|
// Iconos disponibles para categorías
|
||||||
@@ -41,6 +43,7 @@ document.addEventListener('DOMContentLoaded', async () => {
|
|||||||
setupLoginForm();
|
setupLoginForm();
|
||||||
setupLogout();
|
setupLogout();
|
||||||
setupNavigation();
|
setupNavigation();
|
||||||
|
setupSubtabs();
|
||||||
setupModals();
|
setupModals();
|
||||||
setupPermisosToggles();
|
setupPermisosToggles();
|
||||||
setupCategoriasModals();
|
setupCategoriasModals();
|
||||||
@@ -94,19 +97,28 @@ function mostrarDashboard(user) {
|
|||||||
// Aplicar permisos (visibilidad de nav, subsección admin-only, etc.)
|
// Aplicar permisos (visibilidad de nav, subsección admin-only, etc.)
|
||||||
aplicarPermisos();
|
aplicarPermisos();
|
||||||
|
|
||||||
// Reset a la vista dashboard
|
// Determinar vista inicial
|
||||||
cambiarVista('dashboard');
|
const esAdmin = user.rol === 'admin';
|
||||||
|
const perms = getPermisosEfectivos();
|
||||||
|
let viewInicial;
|
||||||
|
if (esAdmin || perms.includes('dashboard')) {
|
||||||
|
viewInicial = 'dashboard';
|
||||||
|
} else {
|
||||||
|
// Primera vista visible según permisos
|
||||||
|
viewInicial = perms[0] || 'descargas';
|
||||||
|
}
|
||||||
|
cambiarVista(viewInicial);
|
||||||
|
|
||||||
cargarEstadisticas();
|
cargarEstadisticas();
|
||||||
}
|
}
|
||||||
|
|
||||||
function cambiarVista(view) {
|
function cambiarVista(view) {
|
||||||
// Check defensivo: si el usuario no tiene permiso para esta vista, redirige a dashboard
|
// Check defensivo: si el usuario no tiene permiso para esta vista, redirige a la primera vista visible
|
||||||
if (currentUser && view !== 'dashboard') {
|
if (currentUser) {
|
||||||
const esAdmin = currentUser.rol === 'admin';
|
const esAdmin = currentUser.rol === 'admin';
|
||||||
const permisos = currentUser.permisos || [];
|
const perms = getPermisosEfectivos();
|
||||||
if (!esAdmin && !permisos.includes(view)) {
|
if (!esAdmin && !perms.includes(view)) {
|
||||||
view = 'dashboard';
|
view = perms[0] || 'descargas';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -150,6 +162,10 @@ function cambiarVista(view) {
|
|||||||
if (view === 'agotados') {
|
if (view === 'agotados') {
|
||||||
cargarAgotados();
|
cargarAgotados();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (view === 'descargas') {
|
||||||
|
cargarDescargas();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function cargarEstadisticas() {
|
async function cargarEstadisticas() {
|
||||||
@@ -172,27 +188,28 @@ async function cargarEstadisticas() {
|
|||||||
|
|
||||||
// ════════════════════════════════
|
// ════════════════════════════════
|
||||||
// PERMISOS — visibilidad según rol + permisos[]
|
// PERMISOS — visibilidad según rol + permisos[]
|
||||||
|
// Vendedor: SIEMPRE ve 'descargas' (implícito) + lo que le hayan dado
|
||||||
// ════════════════════════════════
|
// ════════════════════════════════
|
||||||
|
function getPermisosEfectivos() {
|
||||||
|
if (!currentUser) return [];
|
||||||
|
const permisos = currentUser.permisos || [];
|
||||||
|
if (currentUser.rol === 'vendedor' && !permisos.includes('descargas')) {
|
||||||
|
return ['descargas', ...permisos];
|
||||||
|
}
|
||||||
|
return permisos;
|
||||||
|
}
|
||||||
|
|
||||||
function aplicarPermisos() {
|
function aplicarPermisos() {
|
||||||
if (!currentUser) return;
|
if (!currentUser) return;
|
||||||
|
|
||||||
const esAdmin = currentUser.rol === 'admin';
|
const esAdmin = currentUser.rol === 'admin';
|
||||||
const permisos = currentUser.permisos || [];
|
const perms = getPermisosEfectivos();
|
||||||
const puedeGestionarUsuarios = esAdmin || permisos.includes('usuarios');
|
const puedeGestionarUsuarios = esAdmin || perms.includes('usuarios');
|
||||||
|
|
||||||
// Mostrar/ocultar cada nav-item según permisos
|
// Mostrar/ocultar cada nav-item según permisos
|
||||||
document.querySelectorAll('.nav-item[data-view]').forEach(item => {
|
document.querySelectorAll('.nav-item[data-view]').forEach(item => {
|
||||||
const view = item.dataset.view;
|
const view = item.dataset.view;
|
||||||
let visible = false;
|
const visible = esAdmin || perms.includes(view);
|
||||||
|
|
||||||
if (view === 'dashboard') {
|
|
||||||
visible = true; // Dashboard siempre visible
|
|
||||||
} else if (esAdmin) {
|
|
||||||
visible = true; // Admin ve todo
|
|
||||||
} else {
|
|
||||||
visible = permisos.includes(view); // Editor: solo sus permisos
|
|
||||||
}
|
|
||||||
|
|
||||||
item.style.display = visible ? '' : 'none';
|
item.style.display = visible ? '' : 'none';
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -220,6 +237,35 @@ function setupNavigation() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ════════════════════════════════
|
||||||
|
// SUBTABS (dentro de la view 'descargas')
|
||||||
|
// ════════════════════════════════
|
||||||
|
function setupSubtabs() {
|
||||||
|
document.querySelectorAll('.subtab').forEach(btn => {
|
||||||
|
btn.addEventListener('click', () => {
|
||||||
|
const subtab = btn.dataset.subtab;
|
||||||
|
// Activar solo este botón
|
||||||
|
btn.parentElement.querySelectorAll('.subtab').forEach(b => {
|
||||||
|
b.classList.toggle('active', b === btn);
|
||||||
|
b.setAttribute('aria-selected', b === btn ? 'true' : 'false');
|
||||||
|
});
|
||||||
|
// Mostrar solo el panel correspondiente
|
||||||
|
document.querySelectorAll('.subtab-panel').forEach(p => {
|
||||||
|
p.classList.toggle('active', p.dataset.subtabPanel === subtab);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// ════════════════════════════════
|
||||||
|
// DESCARGAS (vista + subtabs pdf / fotos)
|
||||||
|
// Funcionalidad TBD — placeholders por ahora
|
||||||
|
// ════════════════════════════════
|
||||||
|
function cargarDescargas() {
|
||||||
|
// Placeholder. Cuando se implemente cada subpestaña, se cargan
|
||||||
|
// los datos del backend (PDFs disponibles, lotes de fotos, etc.).
|
||||||
|
}
|
||||||
|
|
||||||
// ════════════════════════════════
|
// ════════════════════════════════
|
||||||
// PERMISOS EN MODALES — render y lectura
|
// PERMISOS EN MODALES — render y lectura
|
||||||
// ════════════════════════════════
|
// ════════════════════════════════
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
<link href="https://fonts.googleapis.com/css2?family=DM+Serif+Display:ital@0;1&family=Plus+Jakarta+Sans:wght@300;400;500;600;700;800&display=swap" rel="stylesheet">
|
<link href="https://fonts.googleapis.com/css2?family=DM+Serif+Display:ital@0;1&family=Plus+Jakarta+Sans:wght@300;400;500;600;700;800&display=swap" rel="stylesheet">
|
||||||
<link rel="stylesheet" href="admin.css?v=5">
|
<link rel="stylesheet" href="admin.css?v=6">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
@@ -73,6 +73,10 @@
|
|||||||
<span class="nav-icon">🚫</span>
|
<span class="nav-icon">🚫</span>
|
||||||
<span class="nav-label">Agotados</span>
|
<span class="nav-label">Agotados</span>
|
||||||
</button>
|
</button>
|
||||||
|
<button type="button" class="nav-item" data-view="descargas">
|
||||||
|
<span class="nav-icon">⬇️</span>
|
||||||
|
<span class="nav-label">Descargas</span>
|
||||||
|
</button>
|
||||||
<button type="button" class="nav-item" data-view="categorias">
|
<button type="button" class="nav-item" data-view="categorias">
|
||||||
<span class="nav-icon">🗂️</span>
|
<span class="nav-icon">🗂️</span>
|
||||||
<span class="nav-label">Categorías</span>
|
<span class="nav-label">Categorías</span>
|
||||||
@@ -233,6 +237,45 @@
|
|||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
<!-- DESCARGAS VIEW (vendedores y otros usuarios con permiso) -->
|
||||||
|
<section class="view" data-view="descargas">
|
||||||
|
<header class="view-header">
|
||||||
|
<h1 class="view-title">Descargas</h1>
|
||||||
|
<p class="view-subtitle">Recursos descargables del catálogo.</p>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<div class="subtabs" role="tablist" aria-label="Tipos de descarga">
|
||||||
|
<button type="button" class="subtab active" data-subtab="pdf" role="tab" aria-selected="true">
|
||||||
|
<span class="subtab-icon">📄</span>
|
||||||
|
<span class="subtab-label">PDF</span>
|
||||||
|
</button>
|
||||||
|
<button type="button" class="subtab" data-subtab="fotos" role="tab" aria-selected="false">
|
||||||
|
<span class="subtab-icon">🖼️</span>
|
||||||
|
<span class="subtab-label">Fotos</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="subtab-panel active" data-subtab-panel="pdf">
|
||||||
|
<div class="view-content-card">
|
||||||
|
<div class="subtab-placeholder">
|
||||||
|
<span class="subtab-placeholder-icon">📄</span>
|
||||||
|
<h3>Descargas en PDF</h3>
|
||||||
|
<p>Próximamente: herramientas para generar y descargar PDFs del catálogo.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="subtab-panel" data-subtab-panel="fotos">
|
||||||
|
<div class="view-content-card">
|
||||||
|
<div class="subtab-placeholder">
|
||||||
|
<span class="subtab-placeholder-icon">🖼️</span>
|
||||||
|
<h3>Descargas de fotos</h3>
|
||||||
|
<p>Próximamente: herramientas para descargar lotes de fotos del catálogo.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
<!-- CATEGORÍAS VIEW -->
|
<!-- CATEGORÍAS VIEW -->
|
||||||
<section class="view" data-view="categorias">
|
<section class="view" data-view="categorias">
|
||||||
<header class="view-header view-header-with-action">
|
<header class="view-header view-header-with-action">
|
||||||
@@ -337,6 +380,7 @@
|
|||||||
<label for="nuevoRol">Rol</label>
|
<label for="nuevoRol">Rol</label>
|
||||||
<select id="nuevoRol" required>
|
<select id="nuevoRol" required>
|
||||||
<option value="editor">Editor</option>
|
<option value="editor">Editor</option>
|
||||||
|
<option value="vendedor">Vendedor</option>
|
||||||
<option value="admin">Administrador</option>
|
<option value="admin">Administrador</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
@@ -382,6 +426,7 @@
|
|||||||
<label for="editarRol">Rol</label>
|
<label for="editarRol">Rol</label>
|
||||||
<select id="editarRol" required>
|
<select id="editarRol" required>
|
||||||
<option value="editor">Editor</option>
|
<option value="editor">Editor</option>
|
||||||
|
<option value="vendedor">Vendedor</option>
|
||||||
<option value="admin">Administrador</option>
|
<option value="admin">Administrador</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
@@ -500,6 +545,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="admin.js?v=5"></script>
|
<script src="admin.js?v=6"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
Reference in New Issue
Block a user