@@ -125,15 +140,9 @@
@@ -204,9 +213,9 @@
-
@@ -254,6 +263,7 @@
fetchStatuses();
fetchServices();
loadCompanies();
+ loadGuilds();
});
function initAutocomplete() {
@@ -278,7 +288,7 @@
document.querySelector('form').reset();
document.getElementById('formTitle').innerHTML = '
Alta de Nuevo Servicio';
document.getElementById('sDate').valueAsDate = new Date();
- document.getElementById('sCreateStatus').disabled = false; // Reactivar al crear
+ document.getElementById('sCreateStatus').disabled = false;
lucide.createIcons();
}
document.getElementById('createServiceView').classList.remove('hidden');
@@ -286,7 +296,7 @@
}
}
- // --- CARGA DE DATOS ---
+ // --- CARGA DE DATOS (Gremios, Operarios, etc) ---
async function fetchStatuses() {
try {
const res = await fetch(`${API_URL}/statuses`, { headers: { "Authorization": `Bearer ${localStorage.getItem("token")}` } });
@@ -303,13 +313,44 @@
} catch(e) {}
}
- // MODIFICADO: Devuelve promesa y no borra si ya existen
+ async function loadGuilds() {
+ try {
+ const res = await fetch(`${API_URL}/guilds`, { headers: { "Authorization": `Bearer ${localStorage.getItem("token")}` } });
+ const data = await res.json();
+ if(data.ok) {
+ const sel = document.getElementById('sGuild');
+ sel.innerHTML = '
';
+ data.guilds.forEach(g => sel.innerHTML += `
`);
+ }
+ } catch(e) {}
+ }
+
+ async function loadOperators(guildId) {
+ const sel = document.getElementById('sOperator');
+ sel.innerHTML = '
';
+ sel.disabled = true;
+
+ if(!guildId) {
+ sel.innerHTML = '
';
+ return;
+ }
+
+ try {
+ const res = await fetch(`${API_URL}/operators?guild_id=${guildId}`, { headers: { "Authorization": `Bearer ${localStorage.getItem("token")}` } });
+ const data = await res.json();
+ if(data.ok) {
+ sel.innerHTML = '
';
+ if(data.operators.length === 0) sel.innerHTML += '
';
+ data.operators.forEach(op => sel.innerHTML += `
`);
+ }
+ } catch(e) { sel.innerHTML = '
'; }
+ finally { sel.disabled = false; }
+ }
+
async function loadCompanies() {
try {
const sel = document.getElementById('sCompanyId');
- // Si ya tiene datos (>1 porque la primera es "--Seleccionar--"), no recargamos
if (sel.options.length > 1) return;
-
const res = await fetch(`${API_URL}/companies`, { headers: { "Authorization": `Bearer ${localStorage.getItem("token")}` } });
const data = await res.json();
if (data.ok) {
@@ -332,130 +373,12 @@
} catch(e) { alert("Error"); }
}
- // --- EDICIÓN Y LOGICA DE FORMULARIO ---
function toggleCompanyFields() {
const isChecked = document.getElementById('sIsCompany').checked;
const div = document.getElementById('companyFields');
- if(isChecked) {
- div.classList.remove('hidden');
- loadCompanies();
- } else {
- div.classList.add('hidden');
- }
+ if(isChecked) { div.classList.remove('hidden'); loadCompanies(); } else { div.classList.add('hidden'); }
}
- async function editService() {
- if(!currentServiceId) return;
- try {
- const res = await fetch(`${API_URL}/services/${currentServiceId}`, { headers: { "Authorization": `Bearer ${localStorage.getItem("token")}` } });
- const json = await res.json();
- if(json.ok) {
- await fillEditForm(json.service); // AWAIT IMPORTANTE
- closeDetailPanel();
- document.getElementById('createServiceView').classList.remove('hidden');
- document.getElementById('servicesListView').classList.add('hidden');
- }
- } catch(e) { showToast("Error cargando datos", true); }
- }
-
- // MODIFICADO: AWAIT para esperar carga de compañías antes de asignar valor
- async function fillEditForm(s) {
- document.getElementById('editServiceId').value = s.id;
- document.getElementById('formTitle').innerHTML = '
Editando Servicio #' + s.id;
-
- document.getElementById('sPhone').value = s.contact_phone;
- document.getElementById('sName').value = s.contact_name;
- document.getElementById('sAddress').value = s.address;
- document.getElementById('sEmail').value = s.email || '';
- document.getElementById('sDesc').value = s.description || '';
-
- if(s.scheduled_date) document.getElementById('sDate').value = s.scheduled_date.split('T')[0];
- if(s.scheduled_time) document.getElementById('sTime').value = s.scheduled_time;
-
- document.getElementById('sDuration').value = s.duration_minutes || 30;
- document.getElementById('sUrgent').checked = s.is_urgent;
-
- document.getElementById('sIsCompany').checked = s.is_company;
-
- // LÓGICA CRÍTICA PARA COMPAÑÍA
- if(s.is_company) {
- document.getElementById('companyFields').classList.remove('hidden');
- await loadCompanies(); // Esperamos a que el select se llene
- document.getElementById('sCompanyId').value = s.company_id || '';
- document.getElementById('sCompanyRef').value = s.company_ref || '';
- } else {
- document.getElementById('companyFields').classList.add('hidden');
- }
-
- document.getElementById('sNotesInternal').value = s.internal_notes || '';
- document.getElementById('sNotesClient').value = s.client_notes || '';
-
- document.getElementById('sCreateStatus').disabled = true; // No editar estado aquí
- lucide.createIcons();
- }
-
- async function handleFormSubmit(e) {
- e.preventDefault();
- const btn = document.getElementById('btnSave');
- btn.disabled = true; btn.innerText = "Procesando...";
-
- const editId = document.getElementById('editServiceId').value;
- const isEdit = !!editId;
-
- const data = {
- phone: document.getElementById('sPhone').value,
- name: document.getElementById('sName').value,
- address: document.getElementById('sAddress').value,
- email: document.getElementById('sEmail').value,
- description: document.getElementById('sDesc').value,
- scheduled_date: document.getElementById('sDate').value,
- scheduled_time: document.getElementById('sTime').value,
- duration: document.getElementById('sDuration').value,
- is_urgent: document.getElementById('sUrgent').checked,
- is_company: document.getElementById('sIsCompany').checked,
- company_id: document.getElementById('sCompanyId').value || null,
- company_ref: document.getElementById('sCompanyRef').value,
- internal_notes: document.getElementById('sNotesInternal').value,
- client_notes: document.getElementById('sNotesClient').value
- };
-
- if (!isEdit) {
- data.status_id = document.getElementById('sCreateStatus').value;
- }
-
- const url = isEdit ? `${API_URL}/services/${editId}` : `${API_URL}/services`;
- const method = isEdit ? 'PUT' : 'POST';
-
- try {
- const res = await fetch(url, {
- method: method,
- headers: { "Content-Type": "application/json", "Authorization": `Bearer ${localStorage.getItem("token")}` },
- body: JSON.stringify(data)
- });
- const json = await res.json();
-
- if (json.ok) {
- showToast(isEdit ? "✅ Actualizado" : "✅ Creado");
- toggleView('list');
- } else {
- showToast("❌ " + (json.error || "Error"), true);
- }
- } catch (e) { showToast("Error conexión", true); }
- finally { btn.disabled = false; btn.innerText = "GUARDAR"; }
- }
-
- async function deleteService() {
- if(!currentServiceId || !confirm("¿Borrar servicio permanentemente?")) return;
- try {
- const res = await fetch(`${API_URL}/services/${currentServiceId}`, {
- method: 'DELETE',
- headers: { "Authorization": `Bearer ${localStorage.getItem("token")}` }
- });
- if(res.ok) { showToast("Eliminado"); closeDetailPanel(); fetchServices(); }
- } catch(e) { showToast("Error", true); }
- }
-
- // --- BÚSQUEDA CLIENTE ---
async function searchClientByPhone() {
const phone = document.getElementById('sPhone').value;
if(phone.length < 8) return;
@@ -498,12 +421,15 @@
const color = s.status_color || 'gray';
const date = new Date(s.created_at);
const formattedDate = date.toLocaleDateString('es-ES', { day: '2-digit', month: 'short' });
+ // Mostramos operario si existe
+ const assigned = s.assigned_name ? `
${s.assigned_name}` : '
Sin asignar';
+
tbody.innerHTML += `
| ${formattedDate} |
${s.contact_name} ${s.address} |
- ${s.description || 'Sin detalles'} ${s.is_urgent ? 'Urgente' : ''}${s.is_company ? `${s.company_name || 'Compañía'}` : ''} |
+ ${assigned} ${s.description || 'Sin detalles'} ${s.is_urgent ? 'Urgente' : ''}${s.is_company ? `${s.company_name || 'Compañía'}` : ''} |
${s.status_name || 'Nuevo'} |
|
@@ -565,6 +491,126 @@
} catch(e) { showToast("Error", true); }
}
+ // --- EDICIÓN Y BORRADO ---
+ async function editService() {
+ if(!currentServiceId) return;
+ try {
+ const res = await fetch(`${API_URL}/services/${currentServiceId}`, { headers: { "Authorization": `Bearer ${localStorage.getItem("token")}` } });
+ const json = await res.json();
+ if(json.ok) {
+ await fillEditForm(json.service);
+ closeDetailPanel();
+ document.getElementById('createServiceView').classList.remove('hidden');
+ document.getElementById('servicesListView').classList.add('hidden');
+ }
+ } catch(e) { showToast("Error cargando datos", true); }
+ }
+
+ async function fillEditForm(s) {
+ document.getElementById('editServiceId').value = s.id;
+ document.getElementById('formTitle').innerHTML = '
Editando Servicio #' + s.id;
+
+ document.getElementById('sPhone').value = s.contact_phone;
+ document.getElementById('sName').value = s.contact_name;
+ document.getElementById('sAddress').value = s.address;
+ document.getElementById('sEmail').value = s.email || '';
+ document.getElementById('sDesc').value = s.description || '';
+
+ if(s.scheduled_date) document.getElementById('sDate').value = s.scheduled_date.split('T')[0];
+ if(s.scheduled_time) document.getElementById('sTime').value = s.scheduled_time;
+ document.getElementById('sDuration').value = s.duration_minutes || 30;
+ document.getElementById('sUrgent').checked = s.is_urgent;
+
+ // COMPAÑÍA
+ document.getElementById('sIsCompany').checked = s.is_company;
+ if(s.is_company) {
+ document.getElementById('companyFields').classList.remove('hidden');
+ await loadCompanies();
+ document.getElementById('sCompanyId').value = s.company_id || '';
+ document.getElementById('sCompanyRef').value = s.company_ref || '';
+ } else {
+ document.getElementById('companyFields').classList.add('hidden');
+ }
+
+ // GREMIO Y OPERARIO (NUEVO)
+ document.getElementById('sGuild').value = s.guild_id || '';
+ if(s.guild_id) {
+ await loadOperators(s.guild_id);
+ document.getElementById('sOperator').value = s.assigned_to || '';
+ } else {
+ loadOperators(''); // Limpiar
+ }
+
+ document.getElementById('sNotesInternal').value = s.internal_notes || '';
+ document.getElementById('sNotesClient').value = s.client_notes || '';
+
+ document.getElementById('sCreateStatus').disabled = true;
+ lucide.createIcons();
+ }
+
+ async function handleFormSubmit(e) {
+ e.preventDefault();
+ const btn = document.getElementById('btnSave');
+ btn.disabled = true; btn.innerText = "Procesando...";
+
+ const editId = document.getElementById('editServiceId').value;
+ const isEdit = !!editId;
+
+ const data = {
+ phone: document.getElementById('sPhone').value,
+ name: document.getElementById('sName').value,
+ address: document.getElementById('sAddress').value,
+ email: document.getElementById('sEmail').value,
+ description: document.getElementById('sDesc').value,
+ scheduled_date: document.getElementById('sDate').value,
+ scheduled_time: document.getElementById('sTime').value,
+ duration: document.getElementById('sDuration').value,
+ is_urgent: document.getElementById('sUrgent').checked,
+ is_company: document.getElementById('sIsCompany').checked,
+ company_id: document.getElementById('sCompanyId').value || null,
+ company_ref: document.getElementById('sCompanyRef').value,
+ internal_notes: document.getElementById('sNotesInternal').value,
+ client_notes: document.getElementById('sNotesClient').value,
+ guild_id: document.getElementById('sGuild').value || null,
+ assigned_to: document.getElementById('sOperator').value || null
+ };
+
+ if (!isEdit) {
+ data.status_id = document.getElementById('sCreateStatus').value;
+ }
+
+ const url = isEdit ? `${API_URL}/services/${editId}` : `${API_URL}/services`;
+ const method = isEdit ? 'PUT' : 'POST';
+
+ try {
+ const res = await fetch(url, {
+ method: method,
+ headers: { "Content-Type": "application/json", "Authorization": `Bearer ${localStorage.getItem("token")}` },
+ body: JSON.stringify(data)
+ });
+ const json = await res.json();
+
+ if (json.ok) {
+ showToast(isEdit ? "✅ Actualizado" : "✅ Creado");
+ toggleView('list');
+ } else {
+ showToast("❌ " + (json.error || "Error"), true);
+ }
+ } catch (e) { showToast("Error conexión", true); }
+ finally { btn.disabled = false; btn.innerText = "GUARDAR"; }
+ }
+
+ async function deleteService() {
+ if(!currentServiceId || !confirm("¿Borrar servicio permanentemente?")) return;
+ try {
+ const res = await fetch(`${API_URL}/services/${currentServiceId}`, {
+ method: 'DELETE',
+ headers: { "Authorization": `Bearer ${localStorage.getItem("token")}` }
+ });
+ if(res.ok) { showToast("Eliminado"); closeDetailPanel(); fetchServices(); }
+ } catch(e) { showToast("Error", true); }
+ }
+
function closeDetailPanel() { document.getElementById('serviceDetailPanel').classList.add('hidden'); }
function showToast(msg, isError = false) {
const t = document.getElementById('toast'), m = document.getElementById('toastMsg');