Initial commit
This commit is contained in:
209
templates/index.html
Normal file
209
templates/index.html
Normal file
@@ -0,0 +1,209 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>medisoftware Kundensuche</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<style>
|
||||
body {
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
.main-content {
|
||||
flex: 1 0 auto;
|
||||
padding: 2rem 0;
|
||||
}
|
||||
.search-container {
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.result-card {
|
||||
margin-bottom: 1rem;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
.result-card:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 8px rgba(0,0,0,0.1);
|
||||
}
|
||||
.loading {
|
||||
display: none;
|
||||
text-align: center;
|
||||
margin: 2rem 0;
|
||||
}
|
||||
.phone-link, .email-link, .address-link, .customer-link {
|
||||
text-decoration: none;
|
||||
color: #0d6efd;
|
||||
}
|
||||
.phone-link:hover, .email-link:hover, .address-link:hover, .customer-link:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
.search-icon {
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
color: #6c757d;
|
||||
}
|
||||
.customer-number {
|
||||
color: #6c757d;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
.footer {
|
||||
flex-shrink: 0;
|
||||
text-align: center;
|
||||
padding: 1rem;
|
||||
background-color: #f8f9fa;
|
||||
border-top: 1px solid #dee2e6;
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="main-content">
|
||||
<div class="container search-container">
|
||||
<h1 class="text-center mb-4">medisoftware Kundensuche</h1>
|
||||
|
||||
<div class="input-group mb-4 position-relative">
|
||||
<input type="text" id="searchInput" class="form-control form-control-lg"
|
||||
placeholder="Suchen Sie nach Name, Fachrichtung, Ort oder Kundennummer...">
|
||||
<span class="search-icon">🔍</span>
|
||||
</div>
|
||||
|
||||
<div id="loading" class="loading">
|
||||
<div class="spinner-border text-primary" role="status">
|
||||
<span class="visually-hidden">Laden...</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="results" class="mt-4">
|
||||
<!-- Hier werden die Suchergebnisse angezeigt -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<footer class="footer">
|
||||
<p class="mb-0">(c) 2025 <a href="https://medisoftware.de" target="_blank" rel="noopener noreferrer" class="text-decoration-none">medisoftware</a></p>
|
||||
</footer>
|
||||
|
||||
<script>
|
||||
let searchTimeout;
|
||||
|
||||
function createPhoneLink(phone) {
|
||||
if (!phone) return 'N/A';
|
||||
// Entferne alle nicht-numerischen Zeichen für den tel: Link
|
||||
const cleaned = phone.replace(/\D/g, '');
|
||||
// Füge immer eine führende 0 hinzu
|
||||
const telLink = '0' + cleaned;
|
||||
// Zeige die ursprüngliche Nummer an
|
||||
return `<a href="tel:${telLink}" class="phone-link">${phone}</a>`;
|
||||
}
|
||||
|
||||
function createEmailLink(email) {
|
||||
if (!email) return 'N/A';
|
||||
return `<a href="mailto:${email}" class="email-link">${email}</a>`;
|
||||
}
|
||||
|
||||
function createAddressLink(street, plz, city) {
|
||||
if (!street || !plz || !city) return 'N/A';
|
||||
const address = `${street}, ${plz} ${city}`;
|
||||
const searchQuery = encodeURIComponent(address);
|
||||
return `<a href="https://www.google.com/maps/search/?api=1&query=${searchQuery}"
|
||||
class="address-link" target="_blank" rel="noopener noreferrer">
|
||||
${address}
|
||||
<span class="ms-1">🗺️</span>
|
||||
</a>`;
|
||||
}
|
||||
|
||||
function createCustomerLink(customerNumber) {
|
||||
if (!customerNumber) return 'N/A';
|
||||
return `<a href="medisw:openkkbefe/P${customerNumber}?NetGrp=4"
|
||||
class="customer-link" target="_blank" rel="noopener noreferrer">
|
||||
${customerNumber}
|
||||
</a>`;
|
||||
}
|
||||
|
||||
function searchCustomers() {
|
||||
const query = document.getElementById('searchInput').value;
|
||||
if (query.length < 2) {
|
||||
document.getElementById('results').innerHTML = '';
|
||||
return;
|
||||
}
|
||||
|
||||
// Lade-Animation anzeigen
|
||||
document.getElementById('loading').style.display = 'block';
|
||||
document.getElementById('results').innerHTML = '';
|
||||
|
||||
fetch(`/search?q=${encodeURIComponent(query)}`)
|
||||
.then(response => {
|
||||
if (!response.ok) {
|
||||
return response.json().then(data => {
|
||||
throw new Error(data.error || 'Ein Fehler ist aufgetreten');
|
||||
});
|
||||
}
|
||||
return response.json();
|
||||
})
|
||||
.then(data => {
|
||||
const resultsDiv = document.getElementById('results');
|
||||
resultsDiv.innerHTML = '';
|
||||
|
||||
if (data.length === 0) {
|
||||
resultsDiv.innerHTML = '<div class="alert alert-info">Keine Ergebnisse gefunden.</div>';
|
||||
return;
|
||||
}
|
||||
|
||||
data.forEach(customer => {
|
||||
const card = document.createElement('div');
|
||||
card.className = 'card result-card';
|
||||
card.innerHTML = `
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">
|
||||
${customer.Vorname} ${customer.Nachname}
|
||||
<span class="customer-number ms-2">(Kunde: ${createCustomerLink(customer.Nummer)})</span>
|
||||
</h5>
|
||||
<p class="card-text">
|
||||
<strong>Fachrichtung:</strong> ${customer.Fachrichtung || 'N/A'}<br>
|
||||
<strong>Adresse:</strong> ${createAddressLink(customer.Strasse, customer.PLZ, customer.Ort)}<br>
|
||||
<strong>Telefon:</strong> ${createPhoneLink(customer.Tel)}<br>
|
||||
<strong>E-Mail:</strong> ${createEmailLink(customer.mail)}
|
||||
</p>
|
||||
</div>
|
||||
`;
|
||||
resultsDiv.appendChild(card);
|
||||
});
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Fehler:', error);
|
||||
document.getElementById('results').innerHTML =
|
||||
`<div class="alert alert-danger">${error.message}</div>`;
|
||||
})
|
||||
.finally(() => {
|
||||
// Lade-Animation ausblenden
|
||||
document.getElementById('loading').style.display = 'none';
|
||||
});
|
||||
}
|
||||
|
||||
// Event-Listener für die Live-Suche
|
||||
document.getElementById('searchInput').addEventListener('input', function(e) {
|
||||
// Clear previous timeout
|
||||
clearTimeout(searchTimeout);
|
||||
|
||||
// Set new timeout
|
||||
searchTimeout = setTimeout(() => {
|
||||
searchCustomers();
|
||||
}, 300); // 300ms Verzögerung
|
||||
});
|
||||
|
||||
// Suche bei Enter-Taste
|
||||
document.getElementById('searchInput').addEventListener('keypress', function(e) {
|
||||
if (e.key === 'Enter') {
|
||||
clearTimeout(searchTimeout);
|
||||
searchCustomers();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
Reference in New Issue
Block a user