From ce80aeeb4a8cc94a2bfd31aa40a914e014bb065e Mon Sep 17 00:00:00 2001 From: James Date: Fri, 20 Mar 2026 00:41:03 -0400 Subject: [PATCH] feat: member inline edit (name/title/email/biz+personal phone); expand/collapse rows; add form includes phone fields --- lib/types.go | 16 +++++----- portal/templates/app/orgs.html | 55 ++++++++++++++++++++++++++-------- 2 files changed, 52 insertions(+), 19 deletions(-) diff --git a/lib/types.go b/lib/types.go index 098537a..c73cc17 100644 --- a/lib/types.go +++ b/lib/types.go @@ -106,13 +106,15 @@ type DealOrgPerms struct { // DealOrgMember is a person associated with a deal org. type DealOrgMember struct { - Name string `json:"name"` - Email string `json:"email"` - Title string `json:"title,omitempty"` - Phone string `json:"phone,omitempty"` - Photo string `json:"photo,omitempty"` - Bio string `json:"bio,omitempty"` - LinkedIn string `json:"linkedin,omitempty"` + Name string `json:"name"` + Email string `json:"email"` + Title string `json:"title,omitempty"` + Phone string `json:"phone,omitempty"` // legacy / kept for compat + PhoneBusiness string `json:"phone_business,omitempty"` + PhonePersonal string `json:"phone_personal,omitempty"` + Photo string `json:"photo,omitempty"` + Bio string `json:"bio,omitempty"` + LinkedIn string `json:"linkedin,omitempty"` } // User represents an account. diff --git a/portal/templates/app/orgs.html b/portal/templates/app/orgs.html index 239af96..c36b34e 100644 --- a/portal/templates/app/orgs.html +++ b/portal/templates/app/orgs.html @@ -109,12 +109,14 @@
-

Add manually

-
+

Add manually

+
+ - - + + +
@@ -228,6 +230,7 @@ if (!o) return; editingOrgId = o.entry_id; editingMembers = (o.members || []).map(m => Object.assign({}, m)); + window._memberExpanded = {}; document.getElementById('eOrgId').value = o.entry_id; document.getElementById('eVersion').value = o.version || 1; document.getElementById('eName').value = o.name || ''; @@ -318,22 +321,51 @@ none.classList.add('hidden'); list.innerHTML = editingMembers.map((m, i) => { const initial = (m.name || m.email || '?')[0].toUpperCase(); - return '
' + const expanded = window._memberExpanded && window._memberExpanded[i]; + return '
' + // header row + + '
' + '
' + escHtml(initial) + '
' + '
' + '
' + escHtml(m.name || m.email || '—') + '
' - + (m.title ? '
' + escHtml(m.title) + '
' : '') - + (m.email && m.name ? '
' + escHtml(m.email) + '
' : '') + + '
' + + [m.title, m.email].filter(Boolean).map(escHtml).join(' · ') + + (m.phone_business ? ' · ' + escHtml(m.phone_business) : '') + + '
' + + '
' + + '' + + '
' + // edit panel (collapsed by default) + + '
' + + '
' + + '
' + + '
' + + '
' + + '
' + + '
' + + '
' + + '' + '
' - + '' + '
'; }).join(''); } + function toggleMemberExpand(i) { + if (!window._memberExpanded) window._memberExpanded = {}; + window._memberExpanded[i] = !window._memberExpanded[i]; + renderMemberList(); + } + + function updateMember(i, field, value) { + if (editingMembers[i]) editingMembers[i][field] = value; + } + function addGlobalMember() { const name = document.getElementById('newMemberName').value.trim(); const email = document.getElementById('newMemberEmail').value.trim(); const title = document.getElementById('newMemberTitle').value.trim(); + const phone_business = document.getElementById('newMemberPhoneBiz').value.trim(); + const phone_personal = document.getElementById('newMemberPhonePersonal').value.trim(); const errEl = document.getElementById('addMemberError'); if (!name && !email) { errEl.textContent = 'Enter a name or email.'; @@ -343,10 +375,9 @@ return; } errEl.classList.add('hidden'); - editingMembers.push({ name, email, title, phone: '', photo: '', bio: '', linkedin: '' }); - document.getElementById('newMemberName').value = ''; - document.getElementById('newMemberEmail').value = ''; - document.getElementById('newMemberTitle').value = ''; + editingMembers.push({ name, email, title, phone_business, phone_personal, photo: '', bio: '', linkedin: '' }); + ['newMemberName','newMemberEmail','newMemberTitle','newMemberPhoneBiz','newMemberPhonePersonal'].forEach(id => document.getElementById(id).value = ''); + window._memberExpanded = {}; renderMemberList(); document.getElementById('newMemberName').focus(); }