432 lines
17 KiB
HTML
432 lines
17 KiB
HTML
<!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 rel="icon" type="image/x-icon" href="{{ url_for('static', filename='favicon.ico') }}">
|
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
|
|
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.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, .reset-icon {
|
|
position: absolute;
|
|
top: 50%;
|
|
transform: translateY(-50%);
|
|
color: #6c757d;
|
|
cursor: pointer;
|
|
display: none;
|
|
z-index: 10;
|
|
}
|
|
.reset-icon {
|
|
right: 10px;
|
|
}
|
|
.search-icon {
|
|
right: 35px;
|
|
}
|
|
.reset-icon.visible {
|
|
display: block;
|
|
}
|
|
.search-icon.visible {
|
|
display: block;
|
|
}
|
|
.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%;
|
|
}
|
|
.share-feedback {
|
|
position: fixed;
|
|
bottom: 20px;
|
|
right: 20px;
|
|
background: #28a745;
|
|
color: white;
|
|
padding: 8px 16px;
|
|
border-radius: 4px;
|
|
display: none;
|
|
animation: fadeOut 2s forwards;
|
|
z-index: 1000;
|
|
}
|
|
@keyframes fadeOut {
|
|
0% { opacity: 1; }
|
|
70% { opacity: 1; }
|
|
100% { opacity: 0; }
|
|
}
|
|
.card-actions {
|
|
display: flex;
|
|
justify-content: flex-end;
|
|
margin-top: 1rem;
|
|
}
|
|
.share-button {
|
|
padding: 5px 10px;
|
|
border-radius: 15px;
|
|
font-size: 0.9em;
|
|
}
|
|
.search-fields {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
|
gap: 1rem;
|
|
margin-bottom: 1rem;
|
|
}
|
|
.search-field {
|
|
position: relative;
|
|
}
|
|
.input-group {
|
|
position: relative;
|
|
}
|
|
.result-counts {
|
|
display: flex;
|
|
justify-content: center;
|
|
margin-bottom: 1rem;
|
|
padding: 0.5rem;
|
|
background-color: #f8f9fa;
|
|
border-radius: 4px;
|
|
}
|
|
.result-count {
|
|
background-color: #e9ecef;
|
|
padding: 4px 12px;
|
|
border-radius: 12px;
|
|
font-size: 0.9em;
|
|
color: #6c757d;
|
|
display: none;
|
|
}
|
|
.result-count.visible {
|
|
display: inline-block;
|
|
}
|
|
.location-pin {
|
|
color: #dc3545;
|
|
margin-left: 4px;
|
|
font-size: 1.2em;
|
|
}
|
|
.weather-info {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
margin-left: 10px;
|
|
font-size: 0.9em;
|
|
color: #666;
|
|
}
|
|
.weather-info img {
|
|
width: 24px;
|
|
height: 24px;
|
|
margin-right: 4px;
|
|
}
|
|
</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="Allgemeine Suche...">
|
|
<i class="fa-solid fa-xmark reset-icon" id="searchReset"></i>
|
|
<span class="search-icon">🔍</span>
|
|
</div>
|
|
|
|
<div class="search-fields">
|
|
<div class="search-field">
|
|
<input type="text" id="nameInput" class="form-control"
|
|
placeholder="Name...">
|
|
<i class="fa-solid fa-xmark reset-icon" id="nameReset"></i>
|
|
</div>
|
|
<div class="search-field">
|
|
<input type="text" id="ortInput" class="form-control"
|
|
placeholder="Ort...">
|
|
<i class="fa-solid fa-xmark reset-icon" id="ortReset"></i>
|
|
</div>
|
|
<div class="search-field">
|
|
<input type="text" id="kundennummerInput" class="form-control"
|
|
placeholder="Kundennummer...">
|
|
<i class="fa-solid fa-xmark reset-icon" id="kundennummerReset"></i>
|
|
</div>
|
|
<div class="search-field">
|
|
<input type="text" id="fachrichtungInput" class="form-control"
|
|
placeholder="Fachrichtung...">
|
|
<i class="fa-solid fa-xmark reset-icon" id="fachrichtungReset"></i>
|
|
</div>
|
|
<div class="search-field">
|
|
<input type="text" id="telefonInput" class="form-control"
|
|
placeholder="Telefon...">
|
|
<i class="fa-solid fa-xmark reset-icon" id="telefonReset"></i>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="result-counts">
|
|
<span id="generalCount" class="result-count"></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>
|
|
|
|
<div id="shareFeedback" class="share-feedback">
|
|
Link kopiert!
|
|
</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;
|
|
let lastResults = [];
|
|
|
|
function createPhoneLink(phone) {
|
|
if (!phone) return 'N/A';
|
|
const cleaned = phone.replace(/\D/g, '');
|
|
const telLink = '0' + cleaned;
|
|
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 `${address}
|
|
<a href="https://www.google.com/maps/search/?api=1&query=${searchQuery}"
|
|
class="address-link" target="_blank" rel="noopener noreferrer">
|
|
<i class="fa-solid fa-location-pin location-pin"></i>
|
|
</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 showCopyFeedback() {
|
|
const feedback = document.getElementById('shareFeedback');
|
|
feedback.style.display = 'block';
|
|
feedback.style.opacity = '1';
|
|
|
|
feedback.addEventListener('animationend', () => {
|
|
feedback.style.display = 'none';
|
|
}, { once: true });
|
|
}
|
|
|
|
async function copyCustomerLink(customerNumber) {
|
|
const url = new URL(window.location.href);
|
|
url.searchParams.set('kundennummer', customerNumber);
|
|
|
|
try {
|
|
await navigator.clipboard.writeText(url.toString());
|
|
showCopyFeedback();
|
|
} catch (err) {
|
|
console.error('Fehler beim Kopieren:', err);
|
|
}
|
|
}
|
|
|
|
function updateResultCounts() {
|
|
// Nur Gesamtzahl anzeigen
|
|
const generalCount = lastResults.length;
|
|
document.getElementById('generalCount').textContent =
|
|
generalCount > 0 ? `${generalCount} Treffer gefunden` : '';
|
|
document.getElementById('generalCount').classList.toggle('visible', generalCount > 0);
|
|
}
|
|
|
|
function searchCustomers() {
|
|
const name = document.getElementById('nameInput').value;
|
|
const ort = document.getElementById('ortInput').value;
|
|
const kundennummer = document.getElementById('kundennummerInput').value;
|
|
const fachrichtung = document.getElementById('fachrichtungInput').value;
|
|
const telefon = document.getElementById('telefonInput').value;
|
|
const query = document.getElementById('searchInput').value;
|
|
|
|
// Prüfe, ob mindestens ein Suchfeld ausgefüllt ist
|
|
if (!name && !ort && !kundennummer && !fachrichtung && !telefon && !query) {
|
|
document.getElementById('results').innerHTML = '';
|
|
lastResults = [];
|
|
updateResultCounts();
|
|
return;
|
|
}
|
|
|
|
// Lade-Animation anzeigen
|
|
document.getElementById('loading').style.display = 'block';
|
|
document.getElementById('results').innerHTML = '';
|
|
|
|
// URL-Parameter erstellen
|
|
const params = new URLSearchParams();
|
|
if (name) params.append('name', name);
|
|
if (ort) params.append('ort', ort);
|
|
if (kundennummer) params.append('kundennummer', kundennummer);
|
|
if (fachrichtung) params.append('fachrichtung', fachrichtung);
|
|
if (telefon) params.append('telefon', telefon);
|
|
if (query) params.append('q', query);
|
|
|
|
fetch(`/search?${params.toString()}`)
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
if (data.error) {
|
|
showError(data.error);
|
|
return;
|
|
}
|
|
|
|
const resultsContainer = document.getElementById('results');
|
|
resultsContainer.innerHTML = '';
|
|
|
|
if (data.results && data.results.length > 0) {
|
|
data.results.forEach(customer => {
|
|
const card = document.createElement('div');
|
|
card.className = 'card mb-3';
|
|
card.innerHTML = `
|
|
<div class="card-body">
|
|
<h5 class="card-title">${customer.Vorname} ${customer.Nachname}</h5>
|
|
<p class="card-text">
|
|
<strong>Kundennummer:</strong> ${customer.Nummer}<br>
|
|
<strong>Fachrichtung:</strong> ${customer.Fachrichtung || 'N/A'}<br>
|
|
<strong>Adresse:</strong> ${createAddressLink(customer.Strasse, customer.PLZ, customer.Ort)}
|
|
${customer.weather ? `
|
|
<span class="weather-info">
|
|
<img src="http://openweathermap.org/img/wn/${customer.weather.icon}@2x.png"
|
|
alt="${customer.weather.description}"
|
|
title="${customer.weather.description}">
|
|
${customer.weather.temperature}°C
|
|
</span>
|
|
` : ''}
|
|
<br>
|
|
<strong>Telefon:</strong> ${createPhoneLink(customer.Tel)}<br>
|
|
<strong>E-Mail:</strong> ${createEmailLink(customer.mail)}
|
|
</p>
|
|
</div>
|
|
`;
|
|
resultsContainer.appendChild(card);
|
|
});
|
|
|
|
// Zeige die Anzahl der Treffer an
|
|
const totalResults = document.getElementById('total-results');
|
|
if (totalResults) {
|
|
totalResults.textContent = `${data.total} Treffer gefunden`;
|
|
}
|
|
} else {
|
|
resultsContainer.innerHTML = '<div class="alert alert-info">Keine Ergebnisse gefunden.</div>';
|
|
}
|
|
})
|
|
.catch(error => {
|
|
console.error('Fehler:', error);
|
|
document.getElementById('results').innerHTML =
|
|
`<div class="alert alert-danger">${error.message}</div>`;
|
|
lastResults = [];
|
|
updateResultCounts();
|
|
})
|
|
.finally(() => {
|
|
document.getElementById('loading').style.display = 'none';
|
|
});
|
|
}
|
|
|
|
// Event-Listener für die Live-Suche
|
|
const searchInputs = [
|
|
document.getElementById('nameInput'),
|
|
document.getElementById('ortInput'),
|
|
document.getElementById('kundennummerInput'),
|
|
document.getElementById('fachrichtungInput'),
|
|
document.getElementById('telefonInput'),
|
|
document.getElementById('searchInput')
|
|
];
|
|
|
|
const resetIcons = [
|
|
document.getElementById('nameReset'),
|
|
document.getElementById('ortReset'),
|
|
document.getElementById('kundennummerReset'),
|
|
document.getElementById('fachrichtungReset'),
|
|
document.getElementById('telefonReset'),
|
|
document.getElementById('searchReset')
|
|
];
|
|
|
|
searchInputs.forEach((input, index) => {
|
|
input.addEventListener('input', function() {
|
|
clearTimeout(searchTimeout);
|
|
searchTimeout = setTimeout(searchCustomers, 300);
|
|
|
|
// Reset-Icon anzeigen/verstecken
|
|
resetIcons[index].classList.toggle('visible', this.value.length > 0);
|
|
});
|
|
|
|
// Reset-Funktionalität
|
|
resetIcons[index].addEventListener('click', function() {
|
|
searchInputs[index].value = '';
|
|
searchCustomers();
|
|
});
|
|
});
|
|
|
|
// URL-Parameter beim Laden der Seite prüfen
|
|
window.addEventListener('load', function() {
|
|
const urlParams = new URLSearchParams(window.location.search);
|
|
const name = urlParams.get('name');
|
|
const ort = urlParams.get('ort');
|
|
const kundennummer = urlParams.get('kundennummer');
|
|
const fachrichtung = urlParams.get('fachrichtung');
|
|
const telefon = urlParams.get('telefon');
|
|
const query = urlParams.get('q');
|
|
|
|
if (name) document.getElementById('nameInput').value = name;
|
|
if (ort) document.getElementById('ortInput').value = ort;
|
|
if (kundennummer) document.getElementById('kundennummerInput').value = kundennummer;
|
|
if (fachrichtung) document.getElementById('fachrichtungInput').value = fachrichtung;
|
|
if (telefon) document.getElementById('telefonInput').value = telefon;
|
|
if (query) document.getElementById('searchInput').value = query;
|
|
|
|
if (name || ort || kundennummer || fachrichtung || telefon || query) {
|
|
searchCustomers();
|
|
}
|
|
});
|
|
</script>
|
|
</body>
|
|
</html> |