UX: Tierarztbesuch-Tab — Praxis-Verknüpfung als Kernfunktion
- Formular: Praxis-Dropdown ersetzt Freitext wenn Praxen vorhanden - Kein redundantes Freitext-Feld mehr, Ort in der Option angezeigt - "Praxis anlegen"-Link navigiert direkt zum Praxen-Tab - tierarzt_name wird zusätzlich als Sicherheitskopie gespeichert - Karte: zeigt Praxisname + Ort unter dem Besuchsgrund - Detail-Modal: Praxis mit Adresse und anklickbarer Telefonnummer - SW-Cache → by-v12
This commit is contained in:
parent
d9f2e85263
commit
e9587d4ecd
2 changed files with 69 additions and 45 deletions
|
|
@ -245,23 +245,32 @@ window.Page_health = (() => {
|
|||
function _renderTierarzt(entries) {
|
||||
const addBtn = `<button class="btn btn-primary btn-sm" data-action="add-entry">+ Besuch eintragen</button>`;
|
||||
if (!entries.length) return UI.emptyState({
|
||||
icon: '🏥', title: 'Noch keine Tierarztbesuche', text: 'Halte alle Tierarztbesuche fest.', action: addBtn
|
||||
icon: '🩺', title: 'Noch keine Tierarztbesuche', text: 'Halte alle Tierarztbesuche fest.', action: addBtn
|
||||
});
|
||||
|
||||
const items = entries.map(e => `
|
||||
<div class="health-card" data-id="${e.id}" data-action="open-entry">
|
||||
<div class="health-card-body">
|
||||
<div class="health-card-title">${_esc(e.bezeichnung)}</div>
|
||||
<div class="health-card-meta">
|
||||
${UI.time.format(e.datum + 'T00:00:00')}
|
||||
${e.tierarzt_name ? ` · ${_esc(e.tierarzt_name)}` : ''}
|
||||
${e.kosten != null ? ` · ${Number(e.kosten).toFixed(2)} €` : ''}
|
||||
const items = entries.map(e => {
|
||||
const praxis = _praxen.find(p => p.id === e.tierarzt_id);
|
||||
const praxisName = praxis?.name || e.tierarzt_name || '';
|
||||
const praxisOrt = praxis ? [praxis.plz, praxis.ort].filter(Boolean).join(' ') : '';
|
||||
return `
|
||||
<div class="health-card" data-id="${e.id}" data-action="open-entry">
|
||||
<div class="health-card-body">
|
||||
<div class="health-card-title">${_esc(e.bezeichnung)}</div>
|
||||
<div class="health-card-meta">
|
||||
${UI.time.format(e.datum + 'T00:00:00')}
|
||||
${e.kosten != null ? ` · ${Number(e.kosten).toFixed(2)} €` : ''}
|
||||
</div>
|
||||
${praxisName ? `
|
||||
<div style="display:flex;align-items:center;gap:var(--space-1);
|
||||
margin-top:var(--space-1);font-size:var(--text-sm);color:var(--c-text-secondary)">
|
||||
🏥 ${_esc(praxisName)}${praxisOrt ? ` · ${_esc(praxisOrt)}` : ''}
|
||||
</div>` : ''}
|
||||
${e.diagnose ? `<div class="health-card-note"><b>Diagnose:</b> ${_esc(e.diagnose)}</div>` : ''}
|
||||
${e.notiz ? `<div class="health-card-note">${_esc(e.notiz)}</div>` : ''}
|
||||
</div>
|
||||
${e.diagnose ? `<div class="health-card-note"><b>Diagnose:</b> ${_esc(e.diagnose)}</div>` : ''}
|
||||
${e.notiz ? `<div class="health-card-note">${_esc(e.notiz)}</div>` : ''}
|
||||
</div>
|
||||
</div>
|
||||
`).join('');
|
||||
`;
|
||||
}).join('');
|
||||
|
||||
return `<div class="health-list">${items}</div>
|
||||
<div style="text-align:center;padding:var(--space-4)">${addBtn}</div>`;
|
||||
|
|
@ -574,7 +583,16 @@ window.Page_health = (() => {
|
|||
const rows = [];
|
||||
if (e.datum) rows.push(['Datum', UI.time.format(e.datum + 'T00:00:00')]);
|
||||
if (e.naechstes) rows.push(['Nächstes', UI.time.format(e.naechstes + 'T00:00:00')]);
|
||||
if (e.tierarzt_name) rows.push(['Tierarzt', _esc(e.tierarzt_name)]);
|
||||
if (e.tierarzt_id) {
|
||||
const praxis = _praxen.find(p => p.id === e.tierarzt_id);
|
||||
if (praxis) {
|
||||
const adresse = [praxis.strasse, [praxis.plz, praxis.ort].filter(Boolean).join(' ')].filter(Boolean).join(', ');
|
||||
const tel = praxis.telefon ? ` · <a href="tel:${_esc(praxis.telefon)}">${_esc(praxis.telefon)}</a>` : '';
|
||||
rows.push(['Praxis', `🏥 ${_esc(praxis.name)}${adresse ? `<br><small style="color:var(--c-text-secondary)">${_esc(adresse)}${tel}</small>` : tel}`]);
|
||||
}
|
||||
} else if (e.tierarzt_name) {
|
||||
rows.push(['Tierarzt', _esc(e.tierarzt_name)]);
|
||||
}
|
||||
if (e.charge_nr) rows.push(['Charge-Nr.', _esc(e.charge_nr)]);
|
||||
if (e.kosten != null) rows.push(['Kosten', `${Number(e.kosten).toFixed(2)} €`]);
|
||||
if (e.diagnose) rows.push(['Diagnose', _esc(e.diagnose)]);
|
||||
|
|
@ -648,17 +666,12 @@ window.Page_health = (() => {
|
|||
const form = document.getElementById('health-form');
|
||||
setTimeout(() => {
|
||||
form?.querySelector('[name="bezeichnung"]')?.focus();
|
||||
// Praxis-Dropdown: Name auto-befüllen
|
||||
const praxisSelect = document.getElementById('health-praxis-select');
|
||||
const nameInput = document.getElementById('health-tierarzt-name-input');
|
||||
if (praxisSelect && nameInput) {
|
||||
praxisSelect.addEventListener('change', () => {
|
||||
const selected = praxisSelect.options[praxisSelect.selectedIndex];
|
||||
if (selected.value) {
|
||||
nameInput.value = selected.dataset.name || selected.textContent.trim();
|
||||
}
|
||||
});
|
||||
}
|
||||
// "Praxis anlegen" Button im Formular
|
||||
form?.querySelector('[data-action="goto-praxen"]')?.addEventListener('click', () => {
|
||||
UI.modal.close();
|
||||
_activeTab = 'praxen';
|
||||
_renderTab();
|
||||
});
|
||||
}, 150);
|
||||
|
||||
document.getElementById('health-form-cancel')?.addEventListener('click', UI.modal.close);
|
||||
|
|
@ -743,25 +756,31 @@ window.Page_health = (() => {
|
|||
`;
|
||||
case 'tierarzt': {
|
||||
const aktivePraxen = _praxen.filter(p => p.aktiv);
|
||||
const praxisDropdown = aktivePraxen.length ? `
|
||||
<div class="form-group">
|
||||
<label class="form-label">Praxis auswählen</label>
|
||||
<select class="form-control" id="health-praxis-select" name="tierarzt_id">
|
||||
<option value="">– Praxis wählen –</option>
|
||||
${aktivePraxen.map(p => `
|
||||
<option value="${p.id}" data-name="${_esc(p.name)}"
|
||||
${entry?.tierarzt_id === p.id ? 'selected' : ''}>
|
||||
${_esc(p.name)}
|
||||
</option>`).join('')}
|
||||
</select>
|
||||
</div>` : '';
|
||||
const praxisField = aktivePraxen.length
|
||||
? `<div class="form-group">
|
||||
<label class="form-label">Behandelnde Praxis</label>
|
||||
<select class="form-control" id="health-praxis-select" name="tierarzt_id">
|
||||
<option value="">– Praxis wählen –</option>
|
||||
${aktivePraxen.map(p => `
|
||||
<option value="${p.id}"
|
||||
${entry?.tierarzt_id === p.id ? 'selected' : ''}>
|
||||
${_esc(p.name)}${p.ort ? ` · ${_esc(p.ort)}` : ''}
|
||||
</option>`).join('')}
|
||||
</select>
|
||||
</div>`
|
||||
: `<div class="form-group">
|
||||
<div style="padding:var(--space-3);background:var(--c-bg);border-radius:var(--radius-md);
|
||||
font-size:var(--text-sm);color:var(--c-text-secondary)">
|
||||
🏥 Noch keine Praxis angelegt —
|
||||
<button type="button" class="btn btn-ghost btn-sm" style="padding:0;font-size:inherit"
|
||||
data-action="goto-praxen">Praxis im Tab Praxen anlegen</button>
|
||||
</div>
|
||||
<label class="form-label" style="margin-top:var(--space-2)">Tierarzt / Praxis (Freitext)</label>
|
||||
<input class="form-control" name="tierarzt_name"
|
||||
value="${_esc(entry?.tierarzt_name || '')}" placeholder="Dr. Muster">
|
||||
</div>`;
|
||||
return `
|
||||
${praxisDropdown}
|
||||
<div class="form-group">
|
||||
<label class="form-label">Tierarzt / Praxis (Freitext)</label>
|
||||
<input class="form-control" type="text" id="health-tierarzt-name-input"
|
||||
name="tierarzt_name" value="${_esc(entry?.tierarzt_name || '')}">
|
||||
</div>
|
||||
${praxisField}
|
||||
<div class="form-group">
|
||||
<label class="form-label">Diagnose</label>
|
||||
<textarea class="form-control" name="diagnose" rows="2">${_esc(entry?.diagnose || '')}</textarea>
|
||||
|
|
@ -845,7 +864,12 @@ window.Page_health = (() => {
|
|||
if (typ === 'gewicht') p.bezeichnung = `${p.wert} kg`;
|
||||
}
|
||||
if (fd.kosten) p.kosten = parseFloat(fd.kosten.toString().replace(',', '.'));
|
||||
if (fd.tierarzt_id) p.tierarzt_id = parseInt(fd.tierarzt_id);
|
||||
if (fd.tierarzt_id) {
|
||||
p.tierarzt_id = parseInt(fd.tierarzt_id);
|
||||
// Praxisname auch als tierarzt_name sichern (bleibt lesbar wenn Praxis inaktiv/gelöscht)
|
||||
const praxis = _praxen.find(x => x.id === p.tierarzt_id);
|
||||
if (praxis) p.tierarzt_name = praxis.name;
|
||||
}
|
||||
if (typ === 'medikament') {
|
||||
p.aktiv = 'aktiv' in fd ? 1 : 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
Offline-Cache + Push Notifications
|
||||
============================================================ */
|
||||
|
||||
const CACHE_VERSION = 'by-v11';
|
||||
const CACHE_VERSION = 'by-v12';
|
||||
const CACHE_STATIC = `${CACHE_VERSION}-static`;
|
||||
|
||||
// Diese Dateien werden beim Install gecacht (App Shell)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue