- ${ (b.status === 'pending' && !isExpired) ? `
-
-
- ` : (b.status === 'paid' ?
- `
Cobrado` :
- `
Cerrado`) }
+
+ ${actionBtns}
@@ -535,8 +573,6 @@ async function downloadPDF(id) {
`;
}).join('');
- lucide.createIcons();
- }
// ------------------ BUSCADOR DE CLIENTES AUTOMÁTICO ------------------
async function searchClientByPhone() {
@@ -681,6 +717,114 @@ async function downloadPDF(id) {
lucide.createIcons();
}
}
+
+ // ------------------ SISTEMA DE CITA Y AGENDA EN TIEMPO REAL ------------------
+ function openAppointmentModal(id, clientName) {
+ document.getElementById('apptBudgetId').value = id;
+ document.getElementById('apptClientName').innerText = clientName || "Cliente";
+ document.getElementById('apptDate').value = "";
+ document.getElementById('apptTime').value = "";
+ document.getElementById('agendaPreview').classList.add('hidden');
+
+ document.getElementById('appointmentModal').classList.remove('hidden');
+ document.getElementById('appointmentModal').classList.add('flex');
+ setTimeout(() => document.getElementById('apptModalSheet').classList.remove('translate-y-full'), 10);
+
+ loadGuilds();
+ }
+
+ function closeAppointmentModal() {
+ document.getElementById('apptModalSheet').classList.add('translate-y-full');
+ setTimeout(() => {
+ document.getElementById('appointmentModal').classList.add('hidden');
+ document.getElementById('appointmentModal').classList.remove('flex');
+ }, 300);
+ }
+
+ async function loadGuilds() {
+ const gSel = document.getElementById('apptGuild');
+ gSel.innerHTML = '
';
+ try {
+ const res = await fetch(`${API_URL}/guilds`, { headers: { "Authorization": `Bearer ${localStorage.getItem("token")}` } });
+ const data = await res.json();
+ gSel.innerHTML = '
';
+ if (data.ok && data.guilds) {
+ data.guilds.forEach(g => { gSel.innerHTML += `
`; });
+ }
+ } catch (e) { gSel.innerHTML = '
'; }
+ }
+
+ async function checkAgendaForDate(dateStr) {
+ const preview = document.getElementById('agendaPreview');
+ const list = document.getElementById('agendaList');
+
+ if(!dateStr) { preview.classList.add('hidden'); return; }
+
+ preview.classList.remove('hidden');
+ list.innerHTML = '
';
+ lucide.createIcons();
+
+ try {
+ const res = await fetch(`${API_URL}/services`, { headers: { "Authorization": `Bearer ${localStorage.getItem("token")}` } });
+ const data = await res.json();
+
+ if(data.ok && data.services) {
+ const dayServices = data.services.filter(s => s.scheduled_date === dateStr && s.status !== 'archived');
+
+ if(dayServices.length === 0) {
+ list.innerHTML = '
Libre: No tienes nada agendado este día.
';
+ return;
+ }
+ dayServices.sort((a, b) => (a.scheduled_time || "23:59").localeCompare(b.scheduled_time || "23:59"));
+ list.innerHTML = dayServices.map(s => {
+ const raw = s.raw_data || {};
+ const pob = raw['Población'] || raw['POBLACION-PROVINCIA'] || raw['Dirección'] || 'Sin ubicación';
+ const time = s.scheduled_time ? s.scheduled_time.substring(0,5) : 'S/H';
+ return `
+
+ ${time}
+ ${pob}
+
+ `;
+ }).join('');
+ }
+ } catch(e) { list.innerHTML = '
Error de conexión.
'; }
+ }
+
+ async function confirmAppointment() {
+ const id = document.getElementById('apptBudgetId').value;
+ const guild_id = document.getElementById('apptGuild').value;
+ const date = document.getElementById('apptDate').value;
+ const time = document.getElementById('apptTime').value;
+
+ if (!guild_id || !date || !time) return showToast("⚠️ Gremio, Fecha y Hora son obligatorios.");
+
+ const btn = document.getElementById('btnConfirmAppt');
+ btn.disabled = true;
+ btn.innerHTML = '
Procesando...';
+
+ const payload = { guild_id: guild_id, date: date, time: time, use_automation: false, assigned_to: 'self' };
+
+ try {
+ const res = await fetch(`${API_URL}/budgets/${id}/convert`, {
+ method: 'POST',
+ headers: { "Content-Type": "application/json", "Authorization": `Bearer ${localStorage.getItem("token")}` },
+ body: JSON.stringify(payload)
+ });
+ const data = await res.json();
+
+ if(data.ok) {
+ showToast("✅ ¡Cita agendada con éxito!");
+ closeAppointmentModal();
+ fetchBudgets();
+ } else { showToast("❌ " + (data.error || "Error al agendar cita.")); }
+ } catch(e) { showToast("❌ Error de conexión al convertir."); }
+ finally {
+ btn.disabled = false;
+ btn.innerHTML = '
Confirmar Cita';
+ lucide.createIcons();
+ }
+ }