fix(web): prefill birthday in contact form for imported contacts
Docker Image bauen und veröffentlichen / docker (push) Successful in 20m27s

This commit is contained in:
2026-09-06 19:27:28 +02:00
parent 8e946964ec
commit b543b46ad2
2 changed files with 47 additions and 1 deletions
+24 -1
View File
@@ -14,7 +14,9 @@ import (
"sort"
"strconv"
"strings"
"time"
"git.arnef.de/arnef/nidus/internal/birthdays"
"git.arnef.de/arnef/nidus/internal/store"
"git.arnef.de/arnef/nidus/internal/web/templates"
vcard "github.com/emersion/go-vcard"
@@ -490,6 +492,27 @@ func photoDataURL(card vcard.Card) string {
return ""
}
// birthdayInputValue returns birthday in the "YYYY-MM-DD" form the contact
// form's <input type="date"> renders. vCards from other clients often store
// the date in vCard 3.0's compact "YYYYMMDD" form or year-less "--MMDD"
// form; a browser date input silently ignores values it can't parse, which
// would leave the field looking empty and drop the birthday on the next
// save. A year-less value can't be shown in a year-bearing date input as-is,
// so it's pre-filled with the current year — the field still shows the
// contact's real month/day (never the blank state the bug produced), and the
// user can correct the year if they know it. Unrecognized values pass
// through unchanged (the empty string for contacts without a birthday).
func birthdayInputValue(birthday string) string {
month, day, year, ok := birthdays.ParseBirthday(birthday)
if !ok {
return birthday
}
if year == 0 {
year = time.Now().Year()
}
return fmt.Sprintf("%04d-%02d-%02d", year, int(month), day)
}
func labeledValues(card vcard.Card, key string) []templates.LabeledValue {
fields := card[key]
out := make([]templates.LabeledValue, 0, len(fields))
@@ -541,7 +564,7 @@ func contactFormFromCard(book, id string, data []byte) (templates.ContactFormDat
Surname: surname,
Organization: card.PreferredValue(vcard.FieldOrganization),
Note: card.PreferredValue(vcard.FieldNote),
Birthday: card.PreferredValue(vcard.FieldBirthday),
Birthday: birthdayInputValue(card.PreferredValue(vcard.FieldBirthday)),
PhotoDataURL: photoDataURL(card),
Phones: ensureAtLeastOne(labeledValues(card, vcard.FieldTelephone)),
Emails: ensureAtLeastOne(labeledValues(card, vcard.FieldEmail)),