Add files via upload

This commit is contained in:
Tomáš Dvořák
2025-05-23 09:35:33 +02:00
committed by GitHub
parent 6850de022b
commit 621b628be9
2 changed files with 62 additions and 74 deletions
+5 -34
View File
@@ -195,19 +195,15 @@ func parseExcelFile(filename string) ([]Contact, error) {
var contacts []Contact var contacts []Contact
// Parse first table (A-D columns) // Parse first table (A-D columns)
contacts = append(contacts, parseTable(f, sheetName, "A", "D", 1)...) contacts = append(contacts, parseTable(f, sheetName)...)
// Parse second table (F-H columns)
contacts = append(contacts, parseTable(f, sheetName, "F", "H", 2)...)
return contacts, nil return contacts, nil
} }
func parseTable(f *excelize.File, sheetName, startCol, endCol string, tableNum int) []Contact { func parseTable(f *excelize.File, sheetName string) []Contact {
var contacts []Contact var contacts []Contact
var currentContact *Contact var currentContact *Contact
// Get all rows in the sheet
rows, err := f.GetRows(sheetName) rows, err := f.GetRows(sheetName)
if err != nil { if err != nil {
log.Printf("Error getting rows: %v", err) log.Printf("Error getting rows: %v", err)
@@ -221,48 +217,23 @@ func parseTable(f *excelize.File, sheetName, startCol, endCol string, tableNum i
return nil return nil
} }
// Column indices
const (
nameCol = 0
phoneCol = 2
servicePhoneCol = 3
mobileKlapkaCol = 4
)
for i := startRow; i < endRow; i++ { for i := startRow; i < endRow; i++ {
row := rows[i] row := rows[i]
if len(row) < 5 { // Ensure we have all required columns
// Skip if row is too short
if len(row) <= nameCol {
continue continue
} }
// Check for "Aktualizace" - end of data
if len(row) > nameCol && strings.Contains(strings.ToLower(row[nameCol]), "aktualizace") {
break
}
// Check for special formatting rows (like "*02(xx)")
if len(row) > 1 && strings.Contains(row[1], "*") {
continue
}
// Get values from columns (new structure: name, position, phone, service phone, mobile)
name := strings.TrimSpace(row[0]) name := strings.TrimSpace(row[0])
position := strings.TrimSpace(row[1]) position := strings.TrimSpace(row[1])
phone := strings.TrimSpace(row[2]) phone := strings.TrimSpace(row[2])
servicePhone := strings.TrimSpace(row[3]) servicePhone := strings.TrimSpace(row[3])
mobileKlapka := "" mobileKlapka := strings.TrimSpace(row[4])
if len(row) > 4 {
mobileKlapka = strings.TrimSpace(row[4])
}
// Clean phone numbers // Clean phone numbers
phone = cleanPhoneNumber(phone) phone = cleanPhoneNumber(phone)
servicePhone = cleanPhoneNumber(servicePhone) servicePhone = cleanPhoneNumber(servicePhone)
// If we have a name, create new contact if name != "" {
if name != "" && !strings.Contains(name, "(") {
currentContact = &Contact{ currentContact = &Contact{
Name: name, Name: name,
Position: position, Position: position,
+57 -40
View File
@@ -55,6 +55,19 @@
</div> </div>
</div> </div>
<!-- Filter Buttons -->
<div class="mb-6 flex flex-wrap gap-2">
<button onclick="filterByTable('all')" class="filter-btn active" data-filter="all">
Všechny kontakty
</button>
<button onclick="filterByTable(1)" class="filter-btn" data-filter="1">
Tabulka 1
</button>
<button onclick="filterByTable(2)" class="filter-btn" data-filter="2">
Tabulka 2
</button>
</div>
<!-- Switcher --> <!-- Switcher -->
<div class="flex items-center justify-center mb-8"> <div class="flex items-center justify-center mb-8">
<div class="inline-flex rounded-md shadow-sm" role="group"> <div class="inline-flex rounded-md shadow-sm" role="group">
@@ -216,26 +229,52 @@
} }
function filterContacts() { function filterContacts() {
const query = document.getElementById('searchInput').value.toLowerCase().trim(); const searchQuery = document.getElementById('searchInput').value.toLowerCase();
// Apply table filter fetch('/api/contacts')
let contacts = allContacts; .then(response => response.json())
if (currentTableFilter !== 'all') { .then(data => {
contacts = contacts.filter(contact => contact.table == currentTableFilter); // Filter both main and internal contacts
const filteredMain = data.contacts.filter(contact =>
contact.name.toLowerCase().includes(searchQuery) ||
(contact.position && contact.position.toLowerCase().includes(searchQuery)) ||
(contact.phone && contact.phone.toLowerCase().includes(searchQuery)) ||
(contact.service_phone && contact.service_phone.toLowerCase().includes(searchQuery))
);
const filteredInternal = data.internal_contacts.filter(contact =>
contact.name.toLowerCase().includes(searchQuery) ||
(contact.position && contact.position.toLowerCase().includes(searchQuery)) ||
(contact.phone && contact.phone.toLowerCase().includes(searchQuery)) ||
(contact.service_phone && contact.service_phone.toLowerCase().includes(searchQuery))
);
// Update display with filtered results
displayFilteredResults(filteredMain, filteredInternal, searchQuery);
})
.catch(error => {
console.error('Error:', error);
});
}
function displayFilteredResults(mainContacts, internalContacts, searchQuery) {
const mainDiv = document.getElementById('contacts');
const internalDiv = document.getElementById('internal-contacts');
mainDiv.innerHTML = mainContacts.map(contact =>
formatContactCard(contact, searchQuery)
).join('');
internalDiv.innerHTML = internalContacts.map(contact =>
formatContactCard(contact, searchQuery)
).join('');
// Show/hide no results message
if (mainContacts.length === 0 && internalContacts.length === 0) {
document.getElementById('noResults').classList.remove('hidden');
} else {
document.getElementById('noResults').classList.add('hidden');
} }
// Apply search filter
if (query) {
contacts = contacts.filter(contact =>
(contact.name && contact.name.toLowerCase().includes(query)) ||
(contact.position && contact.position.toLowerCase().includes(query)) ||
(contact.phone && contact.phone.replace(/\s/g, '').includes(query.replace(/\s/g, ''))) ||
(contact.service_phone && contact.service_phone.replace(/\s/g, '').includes(query.replace(/\s/g, '')))
);
}
filteredContacts = contacts;
displayContacts(filteredContacts, query);
} }
function highlightText(text, query) { function highlightText(text, query) {
@@ -244,28 +283,6 @@
return text.replace(regex, '<span class="search-highlight">$1</span>'); return text.replace(regex, '<span class="search-highlight">$1</span>');
} }
function displayContacts(contacts, searchQuery = '') {
const mainContacts = contacts.filter(contact => !contact.internal);
const internalContacts = contacts.filter(contact => contact.internal);
const mainContactsDiv = document.getElementById('contacts');
const internalContactsDiv = document.getElementById('internal-contacts');
mainContactsDiv.innerHTML = mainContacts.map(contact =>
formatContactCard(contact, searchQuery)
).join('');
internalContactsDiv.innerHTML = internalContacts.map(contact =>
formatContactCard(contact, searchQuery)
).join('');
if (mainContacts.length === 0 && internalContacts.length === 0) {
document.getElementById('noResults').classList.remove('hidden');
} else {
document.getElementById('noResults').classList.add('hidden');
}
}
function formatContactCard(contact, searchQuery) { function formatContactCard(contact, searchQuery) {
const name = contact.name || 'Bez jména'; const name = contact.name || 'Bez jména';
const position = contact.position || ''; const position = contact.position || '';