diff --git a/static/css/styles.css b/static/css/styles.css index 87f9f9d..fb92a59 100644 --- a/static/css/styles.css +++ b/static/css/styles.css @@ -151,6 +151,36 @@ body { position: relative; } +.reset-icon { + position: absolute; + right: 40px; + top: 50%; + transform: translateY(-50%); + cursor: pointer; + color: #6c757d; + z-index: 10; + padding: 0.375rem; + display: none; +} + +.input-group input:not(:placeholder-shown) + .reset-icon { + display: block; +} + +.reset-icon:hover { + color: #dc3545; +} + +.search-icon { + position: absolute; + right: 10px; + top: 50%; + transform: translateY(-50%); + color: #6c757d; + z-index: 10; + padding: 0.375rem; +} + .result-counts { display: flex; justify-content: center; diff --git a/static/js/main.js b/static/js/main.js index e701d86..76ad62e 100644 --- a/static/js/main.js +++ b/static/js/main.js @@ -34,11 +34,23 @@ function createEmailLink(email) { function highlightText(text, searchTerm) { if (!searchTerm || !text) return text; - // Escapen von Sonderzeichen im Suchbegriff - const escapedSearchTerm = searchTerm.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); - // Erstelle einen regulären Ausdruck ohne Wortgrenzen - const regex = new RegExp(escapedSearchTerm, 'gi'); - return text.replace(regex, '$&'); + + // Teile den Suchbegriff in einzelne Wörter + const searchWords = searchTerm.split(/\s+/).filter(word => word.length > 0); + + // Wenn keine Wörter gefunden wurden, gebe den ursprünglichen Text zurück + if (searchWords.length === 0) return text; + + // Erstelle einen regulären Ausdruck für alle Suchwörter + const regexPattern = searchWords + .map(word => word.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')) + .join('|'); + + // Erstelle den regulären Ausdruck + const regex = new RegExp(`(${regexPattern})`, 'gi'); + + // Ersetze alle Übereinstimmungen mit mark-Tags + return text.replace(regex, '$1'); } function createAddressLink(street, plz, city) { @@ -121,18 +133,15 @@ async function copyCustomerLink(customerNumber) { function updateResultCounts() { const resultCount = document.getElementById('result-count'); const exportButton = document.getElementById('exportButton'); - const vcfExportButton = document.getElementById('vcfExportButton'); if (lastResults && lastResults.length > 0) { resultCount.textContent = `${lastResults.length} Ergebnisse gefunden`; resultCount.style.display = 'inline'; exportButton.style.display = 'inline-block'; - vcfExportButton.style.display = 'inline-block'; } else { resultCount.textContent = ''; resultCount.style.display = 'none'; exportButton.style.display = 'none'; - vcfExportButton.style.display = 'none'; } } @@ -205,33 +214,28 @@ function exportToCSV() { document.body.removeChild(link); } -function exportToVCF() { - if (!lastResults || lastResults.length === 0) { - return; - } +function exportToVCF(customer) { + if (!customer) return; - const vcfData = lastResults.map(customer => { - const lines = [ - 'BEGIN:VCARD', - 'VERSION:3.0', - `FN:${customer.vorname} ${customer.nachname}`, - `N:${customer.nachname};${customer.vorname};;`, - `TEL;TYPE=CELL:${customer.telefon || ''}`, - `TEL;TYPE=HOME:${customer.telefon_2 || ''}`, - `EMAIL:${customer.email || ''}`, - `ADR;TYPE=HOME:;;${customer.strasse || ''};${customer.plz || ''};${customer.ort || ''};${customer.land || ''}`, - `ORG:${customer.firma || ''}`, - `NOTE:${customer.notizen || ''}`, - 'END:VCARD' - ]; - return lines.join('\n'); - }).join('\n\n'); + const vcfData = [ + 'BEGIN:VCARD', + 'VERSION:3.0', + `FN:${customer.vorname || ''} ${customer.nachname || ''}`, + `N:${customer.nachname || ''};${customer.vorname || ''};;`, + `TEL;TYPE=CELL:${customer.telefon || ''}`, + `TEL;TYPE=HOME:${customer.telefon_2 || ''}`, + `EMAIL:${customer.email || ''}`, + `ADR;TYPE=HOME:;;${customer.strasse || ''};${customer.plz || ''};${customer.ort || ''};${customer.land || ''}`, + `ORG:${customer.firma || ''}`, + `NOTE:${customer.notizen || ''}`, + 'END:VCARD' + ].join('\n'); const blob = new Blob([vcfData], { type: 'text/vcard;charset=utf-8' }); const url = window.URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; - a.download = `kontakte_${new Date().toISOString().split('T')[0]}.vcf`; + a.download = `kontakt_${customer.vorname || ''}_${customer.nachname || ''}_${new Date().toISOString().split('T')[0]}.vcf`; document.body.appendChild(a); a.click(); window.URL.revokeObjectURL(url); @@ -240,14 +244,14 @@ function exportToVCF() { function displayResults(results) { const resultsDiv = document.getElementById('results'); - const resultCount = document.getElementById('resultCount'); + const resultCount = document.getElementById('result-count'); const generalSearchTerm = document.getElementById('q').value; const nameSearchTerm = document.getElementById('nameInput').value; const fachrichtungSearchTerm = document.getElementById('fachrichtungInput').value; if (!results || results.length === 0) { resultsDiv.innerHTML = '
Keine Ergebnisse gefunden.
'; - resultCount.textContent = '0 Ergebnisse'; + resultCount.textContent = ''; return; } @@ -255,47 +259,59 @@ function displayResults(results) { lastResults = results; const resultsHTML = results.map(customer => { - const highlightedName = highlightText(customer.name, nameSearchTerm); - const highlightedFachrichtung = highlightText(customer.fachrichtung, fachrichtungSearchTerm); - const highlightedGeneral = highlightText(customer.name, generalSearchTerm) || - highlightText(customer.fachrichtung, generalSearchTerm) || - highlightText(customer.ort, generalSearchTerm); - // Hilfsfunktion zum Erstellen von Feldern nur wenn sie Werte haben const createFieldIfValue = (label, value, formatter = (v) => v) => { if (!value || value === 'N/A' || value === 'n/a' || value === 'N/a' || (typeof value === 'string' && value.trim() === '')) return ''; const formattedValue = formatter(value); return `${label}: ${formattedValue}
`; }; + + // Highlighting für alle Felder + const highlightField = (value) => { + if (!value) return value; + let highlighted = value; + if (nameSearchTerm) { + highlighted = highlightText(highlighted, nameSearchTerm); + } + if (fachrichtungSearchTerm) { + highlighted = highlightText(highlighted, fachrichtungSearchTerm); + } + if (generalSearchTerm) { + highlighted = highlightText(highlighted, generalSearchTerm); + } + return highlighted; + }; return `Tags: ${customer.tags.map(tag => `${tag}`).join('')} diff --git a/templates/index.html b/templates/index.html index 4f21dad..866e7b1 100644 --- a/templates/index.html +++ b/templates/index.html @@ -9,6 +9,7 @@ +
@@ -83,10 +84,7 @@