renderer.js

 avatar
unknown
javascript
16 days ago
38 kB
2
Indexable
document.addEventListener('DOMContentLoaded', () => {
    loadContent('dashboard');
    
    document.querySelectorAll('.nav-link').forEach(link => {
        link.addEventListener('click', (e) => {
            e.preventDefault();
            document.querySelectorAll('.nav-link').forEach(n => n.classList.remove('active'));
            e.target.classList.add('active');
            loadContent(e.target.dataset.page);
        });
    });
});

async function loadContent(page) {
    const container = document.getElementById('main-content');
    const title = document.getElementById('page-title');
    
    showLoading();
    try {
        title.textContent = page.charAt(0).toUpperCase() + page.slice(1);
        
        // Updated path construction
        const pagePath = `./src/pages/${page}.html`;
        const response = await fetch(pagePath);
        
        if (!response.ok) {
            throw new Error(`Failed to load page: ${response.status} ${response.statusText}`);
        }
        
        container.innerHTML = await response.text();
        
        if (typeof window[`init${page.charAt(0).toUpperCase() + page.slice(1)}`] === 'function') {
            await window[`init${page.charAt(0).toUpperCase() + page.slice(1)}`]();
        }
    } catch (error) {
        showError(error);
    } finally {
        hideLoading();
    }
}

// ==================== DASHBOARD ====================
window.initDashboard = async () => {
    try {
        const stats = await window.electron.queryDB(`
            SELECT 
                (SELECT COUNT(*) FROM veterinarians) AS vets,
                (SELECT COUNT(*) FROM clients) AS clients,
                (SELECT COUNT(*) FROM pets) AS pets,
                (SELECT COUNT(*) FROM appointments) AS appointments
        `);

        const upcomingAppointments = await window.electron.queryDB(`
            SELECT a.*, p.name AS pet_name, v.name AS vet_name 
            FROM appointments a
            JOIN pets p ON a.pet_id = p.id
            JOIN veterinarians v ON a.vet_id = v.id
            WHERE a.date > NOW()
            ORDER BY a.date ASC
            LIMIT 5
        `);

        // Display stats
        document.getElementById('main-content').innerHTML = `
            <div class="row mb-4">
                <div class="col-md-3">
                    <div class="card text-white bg-primary mb-3">
                        <div class="card-body">
                            <h5 class="card-title">Veterinarians</h5>
                            <p class="card-text display-4">${stats[0].vets}</p>
                        </div>
                    </div>
                </div>
                <div class="col-md-3">
                    <div class="card text-white bg-success mb-3">
                        <div class="card-body">
                            <h5 class="card-title">Clients</h5>
                            <p class="card-text display-4">${stats[0].clients}</p>
                        </div>
                    </div>
                </div>
                <div class="col-md-3">
                    <div class="card text-white bg-info mb-3">
                        <div class="card-body">
                            <h5 class="card-title">Pets</h5>
                            <p class="card-text display-4">${stats[0].pets}</p>
                        </div>
                    </div>
                </div>
                <div class="col-md-3">
                    <div class="card text-white bg-warning mb-3">
                        <div class="card-body">
                            <h5 class="card-title">Appointments</h5>
                            <p class="card-text display-4">${stats[0].appointments}</p>
                        </div>
                    </div>
                </div>
            </div>

            <div class="card">
                <div class="card-header">
                    <h5 class="card-title mb-0">Upcoming Appointments</h5>
                </div>
                <div class="card-body">
                    ${upcomingAppointments.length === 0 ? 
                        '<div class="text-muted">No upcoming appointments</div>' : 
                        `<div class="list-group">
                            ${upcomingAppointments.map(app => `
                                <div class="list-group-item">
                                    <div class="d-flex w-100 justify-content-between">
                                        <h6 class="mb-1">${app.pet_name} - ${app.type}</h6>
                                        <small>${new Date(app.date).toLocaleString()}</small>
                                    </div>
                                    <p class="mb-1">With ${app.vet_name}</p>
                                    <small class="text-muted">Status: ${app.status}</small>
                                </div>
                            `).join('')}
                        </div>`
                    }
                </div>
            </div>
        `;
    } catch (error) {
        showError(error);
    }
};

// ==================== UTILITY FUNCTIONS ====================
function showLoading() {
    document.getElementById('loading').style.display = 'flex';
}

function hideLoading() {
    document.getElementById('loading').style.display = 'none';
}

function showError(error) {
    const container = document.getElementById('main-content');
    container.innerHTML = `
        <div class="alert alert-danger">
            <h5>Error loading content</h5>
            <pre>${error.message}</pre>
        </div>
    `;
}

// ==================== CLIENTS ====================
window.initClients = async () => {
    try {
        const clients = await window.electron.queryDB(`
            SELECT c.*, COUNT(p.id) AS pet_count 
            FROM clients c
            LEFT JOIN pets p ON c.id = p.owner_id
            GROUP BY c.id
        `);

        const tbody = document.getElementById('clients-list');
        if (!tbody) return;

        tbody.innerHTML = clients.length === 0 ? 
            '<tr><td colspan="5" class="text-center">No clients found.</td></tr>' :
            clients.map(client => `
                <tr>
                    <td>${client.name}</td>
                    <td>
                        ${client.email ? `${client.email}<br>` : ''}
                        ${client.phone || ''}
                    </td>
                    <td>${client.address ? client.address.replace(/\n/g, '<br>') : ''}</td>
                    <td>${client.pet_count}</td>
                    <td>
                        <button class="btn btn-sm btn-outline-primary me-2" onclick="loadClientData(${client.id})">
                            <i class="bi bi-pencil"></i>
                        </button>
                        <button class="btn btn-sm btn-outline-danger" onclick="deleteClient(${client.id})">
                            <i class="bi bi-trash"></i>
                        </button>
                    </td>
                </tr>
            `).join('');

        // Add form handler
        const addForm = document.getElementById('addClientForm');
        if (addForm) {
            addForm.addEventListener('submit', handleAddClient);
        }

        // Edit form handler
        const editForm = document.getElementById('editClientForm');
        if (editForm) {
            editForm.addEventListener('submit', handleEditClient);
        }
    } catch (error) {
        showError(error);
    }
};

async function handleAddClient(e) {
    e.preventDefault();
    const form = e.target;
    const formData = new FormData(form);
    const clientData = Object.fromEntries(formData.entries());

    try {
        await window.electron.queryDB(
            'INSERT INTO clients (name, email, phone, address) VALUES (?, ?, ?, ?)',
            [clientData.name, clientData.email, clientData.phone, clientData.address]
        );

        const modalEl = document.getElementById('addClientModal');
        const modal = bootstrap.Modal.getInstance(modalEl);
        
        if (modal) {
            modal.hide();
        } else {
            modalEl.style.display = 'none';
            modalEl.classList.remove('show');
            document.body.classList.remove('modal-open');
            const modalBackdrop = document.querySelector('.modal-backdrop');
            if (modalBackdrop) {
                modalBackdrop.remove();
            }
        }

        form.reset();
        await initClients();
        showToast('Client added successfully', 'success');
    } catch (error) {
        showError(error);
    }
}

async function handleEditClient(e) {
    e.preventDefault();
    const form = e.target;
    const formData = new FormData(form);
    const clientId = formData.get('id');

    try {
        await window.electron.queryDB(
            'UPDATE clients SET name = ?, email = ?, phone = ?, address = ? WHERE id = ?',
            [formData.get('name'), formData.get('email'), formData.get('phone'), formData.get('address'), clientId]
        );

        const modalEl = document.getElementById('editClientModal');
        const modal = bootstrap.Modal.getInstance(modalEl);
        
        if (modal) {
            modal.hide();
        } else {
            modalEl.style.display = 'none';
            modalEl.classList.remove('show');
            document.body.classList.remove('modal-open');
            const modalBackdrop = document.querySelector('.modal-backdrop');
            if (modalBackdrop) {
                modalBackdrop.remove();
            }
        }

        await initClients();
        showToast('Client updated successfully', 'success');
    } catch (error) {
        showError(error);
    }
}

async function loadClientData(id) {
    try {
        const [client] = await window.electron.queryDB(
            'SELECT * FROM clients WHERE id = ?',
            [id]
        );

        if (client) {
            const form = document.getElementById('editClientForm');
            if (!form) return;

            form.elements['id'].value = client.id;
            form.elements['name'].value = client.name;
            form.elements['email'].value = client.email || '';
            form.elements['phone'].value = client.phone || '';
            form.elements['address'].value = client.address || '';

            const modal = new bootstrap.Modal(document.getElementById('editClientModal'));
            modal.show();
        }
    } catch (error) {
        showError(error);
    }
}

async function deleteClient(id) {
    if (!confirm('Are you sure you want to delete this client?')) {
        return;
    }

    try {
        await window.electron.queryDB(
            'DELETE FROM clients WHERE id = ?',
            [id]
        );
        await initClients();
        showToast('Client deleted successfully', 'success');
    } catch (error) {
        showError(error);
    }
}

// ==================== PETS ====================
let currentPetId = null;

async function handleAddPet(e) {
    e.preventDefault();
    const form = e.target;
    const formData = new FormData(form);
    const petData = Object.fromEntries(formData.entries());
    
    // Convert empty string to null for optional fields
    if (!petData.age) petData.age = null;
    if (!petData.species) petData.species = null;
    if (!petData.breed) petData.breed = null;

    try {
        await window.electron.queryDB(
            'INSERT INTO pets (name, species, breed, age, owner_id) VALUES (?, ?, ?, ?, ?)',
            [petData.name, petData.species, petData.breed, petData.age, petData.owner_id]
        );

        const modalEl = document.getElementById('addPetModal');
        const modal = bootstrap.Modal.getInstance(modalEl);
        
        if (modal) {
            modal.hide();
        } else {
            modalEl.style.display = 'none';
            modalEl.classList.remove('show');
            document.body.classList.remove('modal-open');
            const modalBackdrop = document.querySelector('.modal-backdrop');
            if (modalBackdrop) {
                modalBackdrop.remove();
            }
        }

        form.reset();
        await initPets();
        showToast('Pet added successfully', 'success');
    } catch (error) {
        showError(error);
    }
}

async function handleEditPet(e) {
    e.preventDefault();
    const form = e.target;
    const formData = new FormData(form);
    const petId = formData.get('id');
    const petData = Object.fromEntries(formData.entries());
    
    // Convert empty string to null for optional fields
    if (!petData.age) petData.age = null;
    if (!petData.species) petData.species = null;
    if (!petData.breed) petData.breed = null;

    try {
        await window.electron.queryDB(
            'UPDATE pets SET name = ?, species = ?, breed = ?, age = ?, owner_id = ? WHERE id = ?',
            [petData.name, petData.species, petData.breed, petData.age, petData.owner_id, petId]
        );

        const modalEl = document.getElementById('editPetModal');
        const modal = bootstrap.Modal.getInstance(modalEl);
        
        if (modal) {
            modal.hide();
        } else {
            modalEl.style.display = 'none';
            modalEl.classList.remove('show');
            document.body.classList.remove('modal-open');
            const modalBackdrop = document.querySelector('.modal-backdrop');
            if (modalBackdrop) {
                modalBackdrop.remove();
            }
        }

        await initPets();
        showToast('Pet updated successfully', 'success');
    } catch (error) {
        showError(error);
    }
}

async function loadPetData(id) {
    try {
        const [pet] = await window.electron.queryDB(
            'SELECT * FROM pets WHERE id = ?',
            [id]
        );

        if (pet) {
            const form = document.getElementById('editPetForm');
            if (!form) return;

            form.elements['id'].value = pet.id;
            form.elements['name'].value = pet.name;
            form.elements['species'].value = pet.species || '';
            form.elements['breed'].value = pet.breed || '';
            form.elements['age'].value = pet.age || '';
            form.elements['owner_id'].value = pet.owner_id;

            const modal = new bootstrap.Modal(document.getElementById('editPetModal'));
            modal.show();
        }
    } catch (error) {
        showError(error);
    }
}

async function deletePet(id) {
    if (!confirm('Are you sure you want to delete this pet? This will also delete all associated appointments.')) {
        return;
    }

    try {
        // First delete related appointments
        await window.electron.queryDB(
            'DELETE FROM appointments WHERE pet_id = ?',
            [id]
        );
        
        // Then delete the pet
        await window.electron.queryDB(
            'DELETE FROM pets WHERE id = ?',
            [id]
        );
        
        await initPets();
        showToast('Pet deleted successfully', 'success');
    } catch (error) {
        showError(error);
    }
}

async function openMedicalRecords(petId) {
    currentPetId = petId;
    await Promise.all([loadMedications(petId), loadAttachments(petId)]);
    const modal = new bootstrap.Modal(document.getElementById('medicalRecordsModal'));
    modal.show();
}

async function loadMedications(petId) {
    try {
        const medications = await window.electron.queryDB(`
            SELECT m.*, v.name as vet_name 
            FROM pet_medical_records m
            LEFT JOIN veterinarians v ON m.vet_id = v.id
            WHERE m.pet_id = ?
            ORDER BY m.date DESC
        `, [petId]);

        const tbody = document.getElementById('medicationsList');
        if (!tbody) return;

        tbody.innerHTML = medications.length === 0 ? 
            '<tr><td colspan="6" class="text-center">No medication records found</td></tr>' :
            medications.map(med => `
                <tr>
                    <td>${new Date(med.date).toLocaleDateString()}</td>
                    <td>${med.medication_name}</td>
                    <td>${med.dosage}</td>
                    <td>${med.notes || '-'}</td>
                    <td>${med.next_appointment_date ? new Date(med.next_appointment_date).toLocaleDateString() : '-'}</td>
                    <td>${med.vet_name || 'Unknown'}</td>
                </tr>
            `).join('');
    } catch (error) {
        showError(error);
    }
}

async function loadAttachments(petId) {
    try {
        const attachments = await window.electron.queryDB(`
            SELECT a.*, v.name as vet_name 
            FROM pet_attachments a
            LEFT JOIN veterinarians v ON a.uploaded_by = v.id
            WHERE a.pet_id = ?
            ORDER BY a.upload_date DESC
        `, [petId]);

        const tbody = document.getElementById('attachmentsList');
        if (!tbody) return;

        tbody.innerHTML = attachments.length === 0 ? 
            '<tr><td colspan="5" class="text-center">No attachments found</td></tr>' :
            attachments.map(att => `
                <tr>
                    <td>${new Date(att.upload_date).toLocaleDateString()}</td>
                    <td>${att.file_name}</td>
                    <td>${att.description || '-'}</td>
                    <td>${att.vet_name || 'Unknown'}</td>
                    <td>
                        <button class="btn btn-sm btn-outline-primary me-2" onclick="viewAttachment('${att.file_path}')">
                            <i class="bi bi-eye"></i>
                        </button>
                        <button class="btn btn-sm btn-outline-danger" onclick="deleteAttachment(${att.id})">
                            <i class="bi bi-trash"></i>
                        </button>
                    </td>
                </tr>
            `).join('');
    } catch (error) {
        showError(error);
    }
}

async function deleteAttachment(id) {
    if (!confirm('Are you sure you want to delete this attachment?')) {
        return;
    }

    try {
        const [attachment] = await window.electron.queryDB(
            'SELECT file_path FROM pet_attachments WHERE id = ?',
            [id]
        );

        if (attachment) {
            // Delete file from filesystem
            await window.electron.deleteFile(attachment.file_path);
            
            // Delete record from database
            await window.electron.queryDB(
                'DELETE FROM pet_attachments WHERE id = ?',
                [id]
            );

            await loadAttachments(currentPetId);
            showToast('Attachment deleted successfully', 'success');
        }
    } catch (error) {
        showError(error);
    }
}

async function viewAttachment(filePath) {
    try {
        await window.electron.openFile(filePath);
    } catch (error) {
        showError(error);
    }
}

async function handleAddMedication(e) {
    e.preventDefault();
    const form = e.target;
    const formData = new FormData(form);
    
    try {
        const [vet] = await window.electron.queryDB('SELECT id FROM veterinarians LIMIT 1');
        
        await window.electron.queryDB(`
            INSERT INTO pet_medical_records 
            (pet_id, vet_id, date, medication_name, dosage, notes, next_appointment_date)
            VALUES (?, ?, NOW(), ?, ?, ?, ?)
        `, [
            currentPetId,
            vet.id,
            formData.get('medication_name'),
            formData.get('dosage'),
            formData.get('notes') || null,
            formData.get('next_appointment_date') || null
        ]);

        const modal = bootstrap.Modal.getInstance(document.getElementById('addMedicationModal'));
        modal.hide();
        form.reset();
        await loadMedications(currentPetId);
        showToast('Medication record added successfully', 'success');
    } catch (error) {
        showError(error);
    }
}

async function handleUploadAttachment(e) {
    e.preventDefault();
    const form = e.target;
    const fileInput = document.getElementById('attachmentFile');
    const description = document.getElementById('attachmentDescription').value;

    if (!fileInput.files?.length) {
        showToast('Please select a file', 'error');
        return;
    }

    try {
        const file = fileInput.files[0];
        const [vet] = await window.electron.queryDB('SELECT id FROM veterinarians LIMIT 1');
        const uploadResult = await window.electron.uploadFile(file);

        if (uploadResult.success) {
            await window.electron.queryDB(`
                INSERT INTO pet_attachments 
                (pet_id, file_name, file_path, file_type, upload_date, uploaded_by, description)
                VALUES (?, ?, ?, ?, NOW(), ?, ?)
            `, [
                currentPetId,
                file.name,
                uploadResult.filePath,
                file.type,
                vet.id,
                description || null
            ]);

            form.reset();
            await loadAttachments(currentPetId);
            showToast('Attachment uploaded successfully', 'success');
        }
    } catch (error) {
        showError(error);
    }
}

window.initPets = async () => {
    try {
        const [pets, clients] = await Promise.all([
            window.electron.queryDB(`
                SELECT p.*, c.name AS owner_name 
                FROM pets p
                JOIN clients c ON p.owner_id = c.id
                ORDER BY p.name
            `),
            window.electron.queryDB('SELECT id, name FROM clients ORDER BY name')
        ]);

        // Populate owner select dropdowns in both forms
        const ownerSelects = document.querySelectorAll('select[name="owner_id"]');
        ownerSelects.forEach(select => {
            select.innerHTML = `
                <option value="">Select an owner</option>
                ${clients.map(c => `<option value="${c.id}">${c.name}</option>`).join('')}
            `;
        });

        // Render pets table
        const tbody = document.getElementById('pets-list');
        if (!tbody) return;

        tbody.innerHTML = pets.length === 0 ? 
            '<tr><td colspan="5" class="text-center">No pets found.</td></tr>' :
            pets.map(pet => `
                <tr>
                    <td>${pet.name}</td>
                    <td>${pet.species || 'Unknown'} / ${pet.breed || 'Mixed'}</td>
                    <td>${pet.age ? `${pet.age} years` : '-'}</td>
                    <td>${pet.owner_name}</td>
                    <td>
                        <button class="btn btn-sm btn-outline-primary me-2" onclick="loadPetData(${pet.id})">
                            <i class="bi bi-pencil"></i>
                        </button>
                        <button class="btn btn-sm btn-outline-danger" onclick="deletePet(${pet.id})">
                            <i class="bi bi-trash"></i>
                        </button>
                        <button class="btn btn-sm btn-outline-info me-2" onclick="openMedicalRecords(${pet.id})">
                            <i class="bi bi-journal-medical"></i>
                        </button>
                    </td>
                </tr>
            `).join('');

        // Add form handler
        const addForm = document.getElementById('addPetForm');
        if (addForm) {
            addForm.addEventListener('submit', handleAddPet);
        }

        // Edit form handler
        const editForm = document.getElementById('editPetForm');
        if (editForm) {
            editForm.addEventListener('submit', handleEditPet);
        }

        // Medical record handlers
        document.getElementById('addMedicationForm')?.addEventListener('submit', handleAddMedication);
        document.getElementById('uploadAttachmentForm')?.addEventListener('submit', handleUploadAttachment);

    } catch (error) {
        showError(error);
    }
};

// ==================== APPOINTMENTS ====================
window.initAppointments = async () => {
    try {
        const [appointments, pets, vets] = await Promise.all([
            window.electron.queryDB(`
                SELECT 
                    a.*,
                    p.name AS pet_name,
                    c.name AS owner_name,
                    v.name AS vet_name
                FROM appointments a
                JOIN pets p ON a.pet_id = p.id
                JOIN clients c ON p.owner_id = c.id
                JOIN veterinarians v ON a.vet_id = v.id
                ORDER BY a.date DESC
            `),
            window.electron.queryDB('SELECT id, name FROM pets ORDER BY name'),
            window.electron.queryDB('SELECT id, name FROM veterinarians ORDER BY name')
        ]);

        // Populate select dropdowns in both forms
        const petSelects = document.querySelectorAll('select[name="pet_id"]');
        const vetSelects = document.querySelectorAll('select[name="vet_id"]');
        
        petSelects.forEach(select => {
            select.innerHTML = `
                <option value="">Select a pet</option>
                ${pets.map(p => `<option value="${p.id}">${p.name}</option>`).join('')}
            `;
        });
        
        vetSelects.forEach(select => {
            select.innerHTML = `
                <option value="">Select a veterinarian</option>
                ${vets.map(v => `<option value="${v.id}">${v.name}</option>`).join('')}
            `;
        });

        // Render appointments table
        const tbody = document.getElementById('appointments-list');
        tbody.innerHTML = appointments.length === 0 ? 
            '<tr><td colspan="7" class="text-center">No appointments found</td></tr>' :
            appointments.map(app => `
                <tr>
                    <td>${new Date(app.date).toLocaleString()}</td>
                    <td>${app.pet_name}</td>
                    <td>${app.owner_name}</td>
                    <td>${app.vet_name}</td>
                    <td><span class="badge bg-primary">${app.type}</span></td>
                    <td><span class="badge ${getStatusBadge(app.status)}">${app.status}</span></td>
                    <td>
                        <button class="btn btn-sm btn-outline-primary me-2" onclick="loadAppointmentData(${app.id})">
                            <i class="bi bi-pencil"></i>
                        </button>
                        <button class="btn btn-sm btn-outline-danger" onclick="deleteAppointment(${app.id})">
                            <i class="bi bi-trash"></i>
                        </button>
                    </td>
                </tr>
            `).join('');

        // Add form handler
        const addForm = document.getElementById('addAppointmentForm');
        if (addForm) {
            addForm.addEventListener('submit', handleAddAppointment);
        }

        // Edit form handler
        const editForm = document.getElementById('editAppointmentForm');
        if (editForm) {
            editForm.addEventListener('submit', handleEditAppointment);
        }
    } catch (error) {
        showError(error);
    }
};

async function handleAddAppointment(e) {
    e.preventDefault();
    const form = e.target;
    const formData = new FormData(form);
    const appointmentData = Object.fromEntries(formData.entries());

    try {
        // Validate date is not in the past
        if (new Date(appointmentData.date) < new Date()) {
            throw new Error('Appointment date cannot be in the past');
        }

        await window.electron.queryDB(
            'INSERT INTO appointments (pet_id, vet_id, date, type, notes, status) VALUES (?, ?, ?, ?, ?, ?)',
            [
                appointmentData.pet_id,
                appointmentData.vet_id,
                appointmentData.date,
                appointmentData.type,
                appointmentData.notes || null,
                'scheduled'
            ]
        );

        const modalEl = document.getElementById('addAppointmentModal');
        const modal = bootstrap.Modal.getInstance(modalEl);
        
        if (modal) {
            modal.hide();
        } else {
            modalEl.style.display = 'none';
            modalEl.classList.remove('show');
            document.body.classList.remove('modal-open');
            const modalBackdrop = document.querySelector('.modal-backdrop');
            if (modalBackdrop) {
                modalBackdrop.remove();
            }
        }

        form.reset();
        await initAppointments();
        showToast('Appointment added successfully', 'success');
    } catch (error) {
        showError(error);
    }
}

async function handleEditAppointment(e) {
    e.preventDefault();
    const form = e.target;
    const formData = new FormData(form);
    const appointmentId = formData.get('id');
    const appointmentData = Object.fromEntries(formData.entries());

    try {
        // Validate date is not in the past if status is not completed or canceled
        if (appointmentData.status !== 'completed' && appointmentData.status !== 'canceled') {
            if (new Date(appointmentData.date) < new Date()) {
                throw new Error('Appointment date cannot be in the past for active appointments');
            }
        }

        await window.electron.queryDB(
            'UPDATE appointments SET pet_id = ?, vet_id = ?, date = ?, type = ?, notes = ?, status = ? WHERE id = ?',
            [
                appointmentData.pet_id,
                appointmentData.vet_id,
                appointmentData.date,
                appointmentData.type,
                appointmentData.notes || null,
                appointmentData.status,
                appointmentId
            ]
        );

        const modalEl = document.getElementById('editAppointmentModal');
        const modal = bootstrap.Modal.getInstance(modalEl);
        
        if (modal) {
            modal.hide();
        } else {
            modalEl.style.display = 'none';
            modalEl.classList.remove('show');
            document.body.classList.remove('modal-open');
            const modalBackdrop = document.querySelector('.modal-backdrop');
            if (modalBackdrop) {
                modalBackdrop.remove();
            }
        }

        await initAppointments();
        showToast('Appointment updated successfully', 'success');
    } catch (error) {
        showError(error);
    }
}

async function loadAppointmentData(id) {
    try {
        const [appointment] = await window.electron.queryDB(
            'SELECT * FROM appointments WHERE id = ?',
            [id]
        );

        if (appointment) {
            const form = document.getElementById('editAppointmentForm');
            if (!form) return;

            form.elements['id'].value = appointment.id;
            form.elements['pet_id'].value = appointment.pet_id;
            form.elements['vet_id'].value = appointment.vet_id;
            form.elements['date'].value = new Date(appointment.date).toISOString().slice(0, 16);
            form.elements['type'].value = appointment.type;
            form.elements['status'].value = appointment.status;
            form.elements['notes'].value = appointment.notes || '';

            const modal = new bootstrap.Modal(document.getElementById('editAppointmentModal'));
            modal.show();
        }
    } catch (error) {
        showError(error);
    }
}

async function deleteAppointment(id) {
    if (!confirm('Are you sure you want to delete this appointment?')) {
        return;
    }

    try {
        await window.electron.queryDB(
            'DELETE FROM appointments WHERE id = ?',
            [id]
        );
        await initAppointments();
        showToast('Appointment deleted successfully', 'success');
    } catch (error) {
        showError(error);
    }
}

function getStatusBadge(status) {
    const badges = {
        'scheduled': 'bg-primary',
        'completed': 'bg-success',
        'canceled': 'bg-danger'
    };
    return badges[status] || 'bg-secondary';
}

function showToast(message, type = 'success') {
    let toastContainer = document.getElementById('toast-container');
    if (!toastContainer) {
        toastContainer = document.createElement('div');
        toastContainer.id = 'toast-container';
        toastContainer.className = 'position-fixed bottom-0 end-0 p-3';
        document.body.appendChild(toastContainer);
    }
    
    const toast = document.createElement('div');
    toast.className = `toast align-items-center text-white bg-${type} border-0`;
    toast.setAttribute('role', 'alert');
    toast.innerHTML = `
        <div class="d-flex">
            <div class="toast-body">${message}</div>
            <button type="button" class="btn-close btn-close-white me-2 m-auto" data-bs-dismiss="toast"></button>
        </div>
    `;
    
    toastContainer.appendChild(toast);
    const bsToast = new bootstrap.Toast(toast, { autohide: true, delay: 3000 });
    bsToast.show();
    
    toast.addEventListener('hidden.bs.toast', () => toast.remove());
}

function showError(error) {
    console.error('Error:', error);
    showToast(error.message || 'An error occurred', 'danger');
}

// ==================== VETERINARIANS ====================
window.initVeterinarians = async () => {
    try {
        const veterinarians = await window.electron.queryDB(
            `SELECT id, name, email, phone, specialization FROM veterinarians`
        );

        const veterinariansList = document.getElementById('veterinarians-list');
        if (!veterinariansList) return;

        veterinariansList.innerHTML = veterinarians.length === 0 ? 
            '<tr><td colspan="5" class="text-center">No veterinarians found.</td></tr>' : 
            veterinarians.map(vet => `
                <tr>
                    <td>${vet.name}</td>
                    <td>${vet.email || ''}</td>
                    <td>${vet.phone || ''}</td>
                    <td>${vet.specialization || ''}</td>
                    <td>
                        <button class="btn btn-sm btn-outline-primary me-2" onclick="loadVetData(${vet.id})">
                            <i class="bi bi-pencil"></i>
                        </button>
                        <button class="btn btn-sm btn-outline-danger" onclick="deleteVeterinarian(${vet.id})">
                            <i class="bi bi-trash"></i>
                        </button>
                    </td>
                </tr>
            `).join('');

        // Add form handler
        const addForm = document.getElementById('addVeterinarianForm');
        if (addForm) {
            addForm.addEventListener('submit', handleAddVeterinarian);
        }

        // Edit form handler
        const editForm = document.getElementById('editVeterinarianForm');
        if (editForm) {
            editForm.addEventListener('submit', handleEditVeterinarian);
        }
    } catch (error) {
        showError(error);
    }
};

async function handleAddVeterinarian(e) {
    e.preventDefault();
    const form = e.target;
    const formData = new FormData(form);
    const vetData = Object.fromEntries(formData.entries());

    try {
        await window.electron.queryDB(
            'INSERT INTO veterinarians (name, email, phone, specialization) VALUES (?, ?, ?, ?)',
            [vetData.name, vetData.email, vetData.phone, vetData.specialization]
        );

        // Get the modal element and create a Bootstrap modal instance
        const modalEl = document.getElementById('addVeterinarianModal');
        const modal = bootstrap.Modal.getInstance(modalEl);
        
        if (modal) {
            modal.hide();
        } else {
            modalEl.style.display = 'none';
            modalEl.classList.remove('show');
            document.body.classList.remove('modal-open');
            const modalBackdrop = document.querySelector('.modal-backdrop');
            if (modalBackdrop) {
                modalBackdrop.remove();
            }
        }

        form.reset();
        await initVeterinarians();
        showToast('Veterinarian added successfully', 'success');
    } catch (error) {
        showError(error);
    }
}

async function handleEditVeterinarian(e) {
    e.preventDefault();
    const form = e.target;
    const formData = new FormData(form);
    const vetId = formData.get('id');

    try {
        await window.electron.queryDB(
            'UPDATE veterinarians SET name = ?, email = ?, phone = ?, specialization = ? WHERE id = ?',
            [formData.get('name'), formData.get('email'), formData.get('phone'), formData.get('specialization'), vetId]
        );

        const modalEl = document.getElementById('editVeterinarianModal');
        const modal = bootstrap.Modal.getInstance(modalEl);
        
        if (modal) {
            modal.hide();
        } else {
            modalEl.style.display = 'none';
            modalEl.classList.remove('show');
            document.body.classList.remove('modal-open');
            const modalBackdrop = document.querySelector('.modal-backdrop');
            if (modalBackdrop) {
                modalBackdrop.remove();
            }
        }

        await initVeterinarians();
        showToast('Veterinarian updated successfully', 'success');
    } catch (error) {
        showError(error);
    }
}

async function loadVetData(id) {
    try {
        const [vet] = await window.electron.queryDB(
            'SELECT * FROM veterinarians WHERE id = ?',
            [id]
        );

        if (vet) {
            const form = document.getElementById('editVeterinarianForm');
            if (!form) return;

            form.elements['id'].value = vet.id;
            form.elements['name'].value = vet.name;
            form.elements['email'].value = vet.email || '';
            form.elements['phone'].value = vet.phone || '';
            form.elements['specialization'].value = vet.specialization || '';

            const modal = new bootstrap.Modal(document.getElementById('editVeterinarianModal'));
            modal.show();
        }
    } catch (error) {
        showError(error);
    }
}

async function deleteVeterinarian(id) {
    if (!confirm('Are you sure you want to delete this veterinarian?')) {
        return;
    }

    try {
        await window.electron.queryDB(
            'DELETE FROM veterinarians WHERE id = ?',
            [id]
        );
        await initVeterinarians();
        showToast('Veterinarian deleted successfully', 'success');
    } catch (error) {
        showError(error);
    }
}
Editor is loading...
Leave a Comment