summaryrefslogtreecommitdiffstats
path: root/views/admin/person_detail.erb
diff options
context:
space:
mode:
authorKen D'Ambrosio <ken@jots.org>2026-06-09 14:09:19 +0000
committerKen D'Ambrosio <ken@jots.org>2026-06-09 14:09:19 +0000
commita942b4e83d8c3c71020fdc6ae93954ddfa2ea338 (patch)
tree63deaef83c0cab7d4c51b2f95fc03966d21f8e49 /views/admin/person_detail.erb
parentc13a40a970be156a231200c20362636b198d32ec (diff)
Fix New Person flow: redirect to new cluster, show hero face, detect duplicate names
After moving a face to "New Person", the user is now taken directly to that cluster's detail page. If it's a single unnamed cluster, the face is shown prominently at the top. Typing an existing name on the name form triggers a confirm dialog: OK merges into the existing person's cluster, Cancel saves as a new separate person with the same name. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Diffstat (limited to 'views/admin/person_detail.erb')
-rw-r--r--views/admin/person_detail.erb56
1 files changed, 53 insertions, 3 deletions
diff --git a/views/admin/person_detail.erb b/views/admin/person_detail.erb
index 77f27b7..7a1ea0a 100644
--- a/views/admin/person_detail.erb
+++ b/views/admin/person_detail.erb
@@ -26,11 +26,32 @@
<% unless @is_pool %>
<%# ── Name ──────────────────────────────────────────────────────────────── %>
<section style="margin-bottom:20px">
- <form method="post" action="/admin/people/<%= ERB::Util.url_encode(@uuid) %>" class="name-form">
- <input type="text" name="name" value="<%= ERB::Util.html_escape(@name.to_s) %>"
- placeholder="Enter name…" class="name-input" style="max-width:300px">
+ <% if @count == 1 && !@name %>
+ <% m = @members.first; rel = m['rel']; box = m['box'] %>
+ <% parts = rel.split('/'); fname = parts.last; dir_rel = parts[0..-2].join('/') %>
+ <% album_url = dir_rel.empty? ? '/browse/' : "/browse/#{ERB::Util.html_escape(dir_rel)}" %>
+ <div class="new-person-hero">
+ <div class="face-detail-thumb" data-thumb="/thumb/<%= ERB::Util.html_escape(rel) %>">
+ <a href="<%= album_url %>?photo=<%= ERB::Util.url_encode(fname) %>" target="_blank">
+ <img src="/face/<%= ERB::Util.html_escape(rel) %>?box=<%= ERB::Util.html_escape(box.join(',')) %>"
+ width="140" height="140">
+ </a>
+ </div>
+ <p class="update-hint" style="margin-top:8px">Hover to see full photo &middot; Click to open in album</p>
+ </div>
+ <% end %>
+ <form id="name-form" method="post" action="/admin/people/<%= ERB::Util.url_encode(@uuid) %>" class="name-form">
+ <input type="text" name="name" id="name-input"
+ value="<%= ERB::Util.html_escape(@name.to_s) %>"
+ placeholder="Enter name…" class="name-input" style="max-width:300px"
+ autocomplete="off">
<button type="submit" class="btn">Save Name</button>
</form>
+ <form id="merge-into-form" method="post"
+ action="/admin/people/<%= ERB::Util.url_encode(@uuid) %>/merge"
+ style="display:none">
+ <input type="hidden" name="into" id="merge-into-uuid">
+ </form>
</section>
<%# ── Merge entire cluster ──────────────────────────────────────────────── %>
@@ -131,6 +152,35 @@
preview.style.top = y + 'px';
}
+ // Duplicate name check
+ var existingNames = <%= @existing_names_json || '[]' %>;
+ var nameForm = document.getElementById('name-form');
+ var nameInput = document.getElementById('name-input');
+ if (nameForm && nameInput) {
+ var forceNew = false;
+ nameForm.addEventListener('submit', function (e) {
+ if (forceNew) return;
+ var val = nameInput.value.trim();
+ if (!val) return;
+ var match = existingNames.find(function (p) {
+ return p.name.toLowerCase() === val.toLowerCase();
+ });
+ if (match) {
+ e.preventDefault();
+ var msg = '"' + match.name + '" already exists.\n\n'
+ + 'OK — add this photo to ' + match.name + "'s cluster\n"
+ + 'Cancel — create a new separate person named "' + val + '"';
+ if (confirm(msg)) {
+ document.getElementById('merge-into-uuid').value = match.uuid;
+ document.getElementById('merge-into-form').submit();
+ } else {
+ forceNew = true;
+ nameForm.submit();
+ }
+ }
+ });
+ }
+
document.querySelectorAll('.face-detail-thumb').forEach(function (el) {
el.querySelector('img').style.cursor = 'zoom-in';
el.addEventListener('mouseenter', function (e) {