Add files via upload

This commit is contained in:
Tomáš Dvořák
2025-05-23 09:26:43 +02:00
committed by GitHub
parent fc9102090e
commit a364ce33a0
2 changed files with 98 additions and 69 deletions
+25 -11
View File
@@ -24,6 +24,7 @@ type Contact struct {
type ContactData struct { type ContactData struct {
Contacts []Contact `json:"contacts"` Contacts []Contact `json:"contacts"`
InternalContacts []Contact `json:"internal_contacts"`
LastUpdated time.Time `json:"last_updated"` LastUpdated time.Time `json:"last_updated"`
FileHash string `json:"file_hash"` FileHash string `json:"file_hash"`
} }
@@ -85,6 +86,7 @@ func loadData() {
log.Printf("Excel file %s not found, using empty data", xlsxFile) log.Printf("Excel file %s not found, using empty data", xlsxFile)
currentData = &ContactData{ currentData = &ContactData{
Contacts: []Contact{}, Contacts: []Contact{},
InternalContacts: []Contact{},
LastUpdated: time.Now(), LastUpdated: time.Now(),
FileHash: "", FileHash: "",
} }
@@ -115,24 +117,22 @@ func loadData() {
// Use empty data if parsing fails // Use empty data if parsing fails
currentData = &ContactData{ currentData = &ContactData{
Contacts: []Contact{}, Contacts: []Contact{},
InternalContacts: []Contact{},
LastUpdated: time.Now(), LastUpdated: time.Now(),
FileHash: currentHash, FileHash: currentHash,
} }
return return
} }
currentData = &ContactData{ currentData = processContacts(contacts)
Contacts: contacts, currentData.FileHash = currentHash
LastUpdated: time.Now(),
FileHash: currentHash,
}
// Save to cache // Save to cache
if err := saveCachedData(currentData); err != nil { if err := saveCachedData(currentData); err != nil {
log.Printf("Warning: Could not save cached data: %v", err) log.Printf("Warning: Could not save cached data: %v", err)
} }
log.Printf("Loaded %d contacts from Excel file", len(contacts)) log.Printf("Loaded %d contacts from Excel file", len(currentData.Contacts) + len(currentData.InternalContacts))
} }
func calculateFileHash(filename string) (string, error) { func calculateFileHash(filename string) (string, error) {
@@ -214,10 +214,11 @@ func parseTable(f *excelize.File, sheetName, startCol, endCol string, tableNum i
return contacts return contacts
} }
// Skip header rows (first 3 rows based on your description) // Skip first 3 and last 3 lines
startRow := 3 startRow := 3
if len(rows) <= startRow { endRow := len(rows) - 3
return contacts if endRow <= startRow {
return nil
} }
// Column indices // Column indices
@@ -228,7 +229,7 @@ func parseTable(f *excelize.File, sheetName, startCol, endCol string, tableNum i
mobileKlapkaCol = 4 mobileKlapkaCol = 4
) )
for i := startRow; i < len(rows); i++ { for i := startRow; i < endRow; i++ {
row := rows[i] row := rows[i]
// Skip if row is too short // Skip if row is too short
@@ -303,6 +304,19 @@ func cleanPhoneNumber(phone string) string {
return phone return phone
} }
func processContacts(contacts []Contact) *ContactData {
var data ContactData
for _, contact := range contacts {
if strings.Contains(contact.Name, "Interní") {
data.InternalContacts = append(data.InternalContacts, contact)
} else {
data.Contacts = append(data.Contacts, contact)
}
}
data.LastUpdated = time.Now()
return &data
}
func serveIndex(w http.ResponseWriter, r *http.Request) { func serveIndex(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/" { if r.URL.Path != "/" {
http.NotFound(w, r) http.NotFound(w, r)
@@ -344,7 +358,7 @@ func reloadData(w http.ResponseWriter, r *http.Request) {
loadData() loadData()
w.Header().Set("Content-Type", "application/json") w.Header().Set("Content-Type", "application/json")
fmt.Fprintf(w, `{"status": "reloaded", "contacts_count": %d}`, len(currentData.Contacts)) fmt.Fprintf(w, `{"status": "reloaded", "contacts_count": %d}`, len(currentData.Contacts) + len(currentData.InternalContacts))
} }
func getEmbeddedHTML() string { func getEmbeddedHTML() string {
+33 -18
View File
@@ -80,7 +80,19 @@
<div id="stats" class="mb-6 p-4 bg-gray-50 rounded-lg border text-sm text-gray-700"></div> <div id="stats" class="mb-6 p-4 bg-gray-50 rounded-lg border text-sm text-gray-700"></div>
<!-- Contacts Grid --> <!-- Contacts Grid -->
<div class="container">
<h1>Kontakty</h1>
<div class="section">
<h2>Hlavní kontakty</h2>
<div id="contacts" class="grid gap-6 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4"></div> <div id="contacts" class="grid gap-6 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4"></div>
</div>
<div class="section">
<h2>Interní kontakty</h2>
<div id="internal-contacts" class="grid gap-6 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4"></div>
</div>
</div>
<!-- No Results --> <!-- No Results -->
<div id="noResults" class="hidden text-center py-16"> <div id="noResults" class="hidden text-center py-16">
@@ -228,27 +240,33 @@
} }
function displayContacts(contacts, searchQuery = '') { function displayContacts(contacts, searchQuery = '') {
const container = document.getElementById('contacts'); const mainContacts = contacts.filter(contact => !contact.internal);
const noResults = document.getElementById('noResults'); const internalContacts = contacts.filter(contact => contact.internal);
if (contacts.length === 0) { const mainContactsDiv = document.getElementById('contacts');
container.innerHTML = ''; const internalContactsDiv = document.getElementById('internal-contacts');
noResults.classList.remove('hidden');
return; 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');
}
} }
noResults.classList.add('hidden'); function formatContactCard(contact, searchQuery) {
container.innerHTML = '';
contacts.forEach(contact => {
const contactCard = document.createElement('div');
contactCard.className = 'contact-card bg-white p-6 rounded-lg border border-gray-200 hover:shadow-lg transition-all duration-200';
const name = contact.name || 'Bez jména'; const name = contact.name || 'Bez jména';
const position = contact.position || ''; const position = contact.position || '';
const tableColor = contact.table === 1 ? 'bg-blue-100 text-blue-800' : 'bg-purple-100 text-purple-800'; const tableColor = contact.table === 1 ? 'bg-blue-100 text-blue-800' : 'bg-purple-100 text-purple-800';
contactCard.innerHTML = ` return `<div class="contact-card bg-white p-6 rounded-lg border border-gray-200 hover:shadow-lg transition-all duration-200">
<div class="flex items-start justify-between mb-3"> <div class="flex items-start justify-between mb-3">
<h3 class="font-bold text-gray-800 text-lg leading-tight">${highlightText(name, searchQuery)}</h3> <h3 class="font-bold text-gray-800 text-lg leading-tight">${highlightText(name, searchQuery)}</h3>
<span class="text-xs ${tableColor} px-2 py-1 rounded-full font-medium flex-shrink-0 ml-2">T${contact.table}</span> <span class="text-xs ${tableColor} px-2 py-1 rounded-full font-medium flex-shrink-0 ml-2">T${contact.table}</span>
@@ -275,10 +293,7 @@
` : ''} ` : ''}
${!contact.phone && !contact.service_phone ? '<p class="text-gray-400 text-sm italic">Bez telefonu</p>' : ''} ${!contact.phone && !contact.service_phone ? '<p class="text-gray-400 text-sm italic">Bez telefonu</p>' : ''}
</div> </div>
`; </div>`;
container.appendChild(contactCard);
});
} }
async function reloadContacts() { async function reloadContacts() {