275 lines
11 KiB
PHP

@extends('layouts.app')
@section('title', __('app.patients'))
@section('page_title', __('app.patients'))
@section('content')
<div class="container-fluid">
<div class="row">
<div class="col-12">
<div class="card">
<div class="card-header">
<h3 class="card-title">{{ __('app.patients') }}</h3>
<div class="card-tools">
<div class="input-group input-group-sm" style="width: 250px;">
<input type="text" id="search-patients" class="form-control float-right" placeholder="{{ __('app.search') }}...">
<div class="input-group-append">
<button type="button" class="btn btn-default" onclick="loadPatients()">
<i class="fas fa-search"></i>
</button>
</div>
</div>
<button class="btn btn-primary btn-sm ml-2" onclick="showCreateModal()">
<i class="fas fa-plus"></i> {{ __('app.create') }}
</button>
</div>
</div>
<div class="card-body table-responsive p-0">
<table class="table table-hover text-nowrap" id="patients-table">
<thead>
<tr>
<th>{{ __('app.code') ?? 'Code' }}</th>
<th>{{ __('app.name') }}</th>
<th>{{ __('app.phone') ?? 'Phone' }}</th>
<th>{{ __('app.email') }}</th>
<th>{{ __('app.status') }}</th>
<th>{{ __('app.actions') }}</th>
</tr>
</thead>
<tbody id="patients-tbody">
<tr>
<td colspan="6" class="text-center">{{ __('app.loading') ?? 'Loading...' }}</td>
</tr>
</tbody>
</table>
</div>
<div class="card-footer clearfix" id="pagination-container">
</div>
</div>
</div>
</div>
</div>
<!-- Create/Edit Modal -->
<div class="modal fade" id="patientModal" tabindex="-1">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="modalTitle">{{ __('app.create') }}</h5>
<button type="button" class="close" data-dismiss="modal">&times;</button>
</div>
<form id="patientForm" onsubmit="savePatient(event)">
<div class="modal-body">
<div id="form-errors" class="alert alert-danger d-none"></div>
<input type="hidden" id="patient_id">
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label>{{ __('app.first_name') ?? 'First Name' }} *</label>
<input type="text" class="form-control" name="first_name" required>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label>{{ __('app.last_name') ?? 'Last Name' }} *</label>
<input type="text" class="form-control" name="last_name" required>
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label>{{ __('app.phone') ?? 'Phone' }}</label>
<input type="tel" class="form-control" name="phone">
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label>{{ __('app.whatsapp') ?? 'WhatsApp' }}</label>
<input type="tel" class="form-control" name="whatsapp">
</div>
</div>
</div>
<div class="form-group">
<label>{{ __('app.email') }}</label>
<input type="email" class="form-control" name="email">
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">{{ __('app.cancel') }}</button>
<button type="submit" class="btn btn-primary">{{ __('app.save') }}</button>
</div>
</form>
</div>
</div>
</div>
@endsection
@push('scripts')
<script src="{{ asset('js/api.js') }}"></script>
<script>
let currentPage = 1;
// Load patients on page load
document.addEventListener('DOMContentLoaded', function() {
loadPatients();
});
// Search on Enter key
document.getElementById('search-patients').addEventListener('keypress', function(e) {
if (e.key === 'Enter') {
loadPatients();
}
});
async function loadPatients(page = 1) {
currentPage = page;
const search = document.getElementById('search-patients').value;
try {
const response = await api.getPatients({
search: search,
page: page,
per_page: 20
});
renderPatients(response.data);
renderPagination(response.meta, response.links);
} catch (error) {
console.error('Failed to load patients:', error);
}
}
function renderPatients(patients) {
const tbody = document.getElementById('patients-tbody');
if (patients.length === 0) {
tbody.innerHTML = '<tr><td colspan="6" class="text-center">{{ __("app.no_results") ?? "No patients found" }}</td></tr>';
return;
}
tbody.innerHTML = patients.map(patient => `
<tr>
<td>${patient.patient_code}</td>
<td>${patient.full_name}</td>
<td>${patient.phone || '-'}</td>
<td>${patient.email || '-'}</td>
<td>
<span class="badge badge-${patient.status === 'active' ? 'success' : 'secondary'}">
${patient.status}
</span>
</td>
<td>
<button class="btn btn-sm btn-info" onclick="editPatient(${patient.id})">
<i class="fas fa-edit"></i>
</button>
<button class="btn btn-sm btn-danger" onclick="deletePatient(${patient.id})">
<i class="fas fa-trash"></i>
</button>
</td>
</tr>
`).join('');
}
function renderPagination(meta, links) {
const container = document.getElementById('pagination-container');
let html = '<ul class="pagination pagination-sm m-0 float-right">';
// Previous
if (meta.current_page > 1) {
html += `<li class="page-item"><a class="page-link" href="#" onclick="loadPatients(${meta.current_page - 1})">«</a></li>`;
}
// Page numbers
for (let i = 1; i <= meta.last_page; i++) {
if (i === meta.current_page) {
html += `<li class="page-item active"><span class="page-link">${i}</span></li>`;
} else if (i === 1 || i === meta.last_page || (i >= meta.current_page - 1 && i <= meta.current_page + 1)) {
html += `<li class="page-item"><a class="page-link" href="#" onclick="loadPatients(${i})">${i}</a></li>`;
} else if (i === meta.current_page - 2 || i === meta.current_page + 2) {
html += `<li class="page-item disabled"><span class="page-link">...</span></li>`;
}
}
// Next
if (meta.current_page < meta.last_page) {
html += `<li class="page-item"><a class="page-link" href="#" onclick="loadPatients(${meta.current_page + 1})">»</a></li>`;
}
html += '</ul>';
container.innerHTML = html;
}
function showCreateModal() {
document.getElementById('patientForm').reset();
document.getElementById('patient_id').value = '';
document.getElementById('modalTitle').textContent = '{{ __("app.create") }} {{ __("app.patient") }}';
document.getElementById('form-errors').classList.add('d-none');
$('#patientModal').modal('show');
}
async function editPatient(id) {
try {
const patient = await api.getPatient(id);
document.getElementById('patient_id').value = patient.data.id;
document.querySelector('[name="first_name"]').value = patient.data.first_name;
document.querySelector('[name="last_name"]').value = patient.data.last_name;
document.querySelector('[name="phone"]').value = patient.data.phone || '';
document.querySelector('[name="whatsapp"]').value = patient.data.whatsapp || '';
document.querySelector('[name="email"]').value = patient.data.email || '';
document.getElementById('modalTitle').textContent = '{{ __("app.edit") }} {{ __("app.patient") }}';
document.getElementById('form-errors').classList.add('d-none');
$('#patientModal').modal('show');
} catch (error) {
console.error('Failed to load patient:', error);
}
}
async function savePatient(event) {
event.preventDefault();
const form = event.target;
const data = {
first_name: form.first_name.value,
last_name: form.last_name.value,
phone: form.phone.value,
whatsapp: form.whatsapp.value,
email: form.email.value || null,
};
const id = document.getElementById('patient_id').value;
const errorDiv = document.getElementById('form-errors');
try {
if (id) {
await api.updatePatient(id, data);
api.showSuccess('Patient updated successfully');
} else {
await api.createPatient(data);
api.showSuccess('Patient created successfully');
}
$('#patientModal').modal('hide');
loadPatients(currentPage);
} catch (error) {
errorDiv.textContent = error.message;
errorDiv.classList.remove('d-none');
}
}
async function deletePatient(id) {
if (!confirm('{{ __("app.confirm_delete") ?? "Are you sure?" }}')) return;
try {
await api.deletePatient(id);
api.showSuccess('Patient deleted successfully');
loadPatients(currentPage);
} catch (error) {
console.error('Failed to delete patient:', error);
}
}
</script>
@endpush