feat(web): split contact name into first and last name

This commit is contained in:
2026-08-31 22:08:53 +02:00
parent ea917b4148
commit c945e785c8
3 changed files with 354 additions and 237 deletions
+24 -15
View File
@@ -239,7 +239,8 @@ func (s *Server) handleContactEdit(w http.ResponseWriter, r *http.Request) {
// contactFormInput holds the parsed, validated-ish values submitted by the
// contact form, before they're translated into vCard fields.
type contactFormInput struct {
FullName string
Forename string
Surname string
Organization string
Note string
Birthday string
@@ -284,7 +285,8 @@ func parseContactForm(r *http.Request) (contactFormInput, error) {
get := func(key string) []string { return form[key] }
in := contactFormInput{
FullName: strings.TrimSpace(formValue(get("full_name"), 0)),
Forename: strings.TrimSpace(formValue(get("forename"), 0)),
Surname: strings.TrimSpace(formValue(get("surname"), 0)),
Organization: strings.TrimSpace(formValue(get("organization"), 0)),
Note: strings.TrimSpace(formValue(get("note"), 0)),
Birthday: strings.TrimSpace(formValue(get("birthday"), 0)),
@@ -358,11 +360,12 @@ func (s *Server) saveContactFromForm(w http.ResponseWriter, r *http.Request, use
return
}
if in.FullName == "" {
if in.Forename == "" && in.Surname == "" {
form := templates.ContactFormData{
Book: book,
ID: id,
FullName: in.FullName,
Forename: in.Forename,
Surname: in.Surname,
Organization: in.Organization,
Note: in.Note,
Birthday: in.Birthday,
@@ -371,7 +374,7 @@ func (s *Server) saveContactFromForm(w http.ResponseWriter, r *http.Request, use
Addresses: ensureAtLeastOne(in.Addresses),
}
w.Header().Set("Content-Type", "text/html; charset=utf-8")
_ = templates.ContactForm(username, form, "Full name is required").Render(context.Background(), w)
_ = templates.ContactForm(username, form, "Name is required").Render(context.Background(), w)
return
}
@@ -422,16 +425,10 @@ func buildCard(uid string, in contactFormInput, existingPhoto string) vcard.Card
if uid != "" {
card.SetValue(vcard.FieldUID, uid)
}
card.SetValue(vcard.FieldFormattedName, in.FullName)
name := &vcard.Name{}
parts := strings.Fields(in.FullName)
if len(parts) > 0 {
name.GivenName = parts[0]
}
if len(parts) > 1 {
name.FamilyName = strings.Join(parts[1:], " ")
if fn := strings.TrimSpace(in.Forename + " " + in.Surname); fn != "" {
card.SetValue(vcard.FieldFormattedName, fn)
}
name := &vcard.Name{GivenName: in.Forename, FamilyName: in.Surname}
card.SetName(name)
if in.Organization != "" {
@@ -547,10 +544,22 @@ func contactFormFromCard(book, id string, data []byte) (templates.ContactFormDat
if err != nil {
return templates.ContactFormData{}, err
}
var forename, surname string
if n := card.Name(); n != nil && (n.GivenName != "" || n.FamilyName != "") {
forename, surname = n.GivenName, n.FamilyName
} else if fn := strings.TrimSpace(card.PreferredValue(vcard.FieldFormattedName)); fn != "" {
parts := strings.Fields(fn)
if len(parts) > 1 {
forename, surname = parts[0], strings.Join(parts[1:], " ")
} else {
forename = parts[0]
}
}
return templates.ContactFormData{
Book: book,
ID: id,
FullName: card.PreferredValue(vcard.FieldFormattedName),
Forename: forename,
Surname: surname,
Organization: card.PreferredValue(vcard.FieldOrganization),
Note: card.PreferredValue(vcard.FieldNote),
Birthday: card.PreferredValue(vcard.FieldBirthday),