feat(31-01): add responsive icon buttons to candidate detail page

Replace text action buttons (Edit, Pick as winner, Delete) with
icon-only buttons on mobile viewports (below md: breakpoint). Desktop
retains full text+icon buttons. All icon buttons have aria-label and
44px touch targets.
This commit is contained in:
2026-04-12 20:14:58 +02:00
parent 7effedea3f
commit b6f12fa93d

View File

@@ -279,14 +279,27 @@ function CandidateDetailPage() {
{candidate.name}
</h1>
{isActive && (
<button
type="button"
onClick={enterEditMode}
className="shrink-0 inline-flex items-center gap-1.5 px-3 py-1.5 text-sm text-gray-500 hover:text-gray-700 hover:bg-gray-100 rounded-lg transition-colors"
>
<LucideIcon name="pencil" size={14} />
Edit
</button>
<>
{/* Edit — desktop */}
<button
type="button"
onClick={enterEditMode}
className="shrink-0 hidden md:inline-flex items-center gap-1.5 px-3 py-1.5 text-sm text-gray-500 hover:text-gray-700 hover:bg-gray-100 rounded-lg transition-colors"
>
<LucideIcon name="pencil" size={14} />
Edit
</button>
{/* Edit — mobile */}
<button
type="button"
onClick={enterEditMode}
className="shrink-0 md:hidden inline-flex items-center justify-center min-w-[44px] min-h-[44px] p-2 text-gray-500 hover:text-gray-700 hover:bg-gray-100 rounded-lg transition-colors"
aria-label="Edit"
title="Edit"
>
<LucideIcon name="pencil" size={16} />
</button>
</>
)}
</div>
)}
@@ -529,22 +542,44 @@ function CandidateDetailPage() {
{/* Thread-specific actions */}
{!isEditing && isActive && (
<div className="flex gap-3 pt-4 border-t border-gray-100">
{/* Pick as winner — desktop */}
<button
type="button"
onClick={() => openResolveDialog(threadId, candidateId)}
className="inline-flex items-center gap-1.5 px-4 py-2 bg-amber-50 hover:bg-amber-100 text-amber-700 text-sm font-medium rounded-lg transition-colors"
className="hidden md:inline-flex items-center gap-1.5 px-4 py-2 bg-amber-50 hover:bg-amber-100 text-amber-700 text-sm font-medium rounded-lg transition-colors"
>
<LucideIcon name="trophy" size={14} />
Pick as winner
</button>
{/* Pick as winner — mobile */}
<button
type="button"
onClick={() => openResolveDialog(threadId, candidateId)}
className="md:hidden inline-flex items-center justify-center min-w-[44px] min-h-[44px] p-2 bg-amber-50 hover:bg-amber-100 text-amber-700 rounded-lg transition-colors"
aria-label="Pick as winner"
title="Pick as winner"
>
<LucideIcon name="trophy" size={16} />
</button>
{/* Delete — desktop */}
<button
type="button"
onClick={() => openConfirmDeleteCandidate(candidateId)}
className="inline-flex items-center gap-1.5 px-4 py-2 text-sm text-red-500 hover:text-red-600 hover:bg-red-50 rounded-lg transition-colors"
className="hidden md:inline-flex items-center gap-1.5 px-4 py-2 text-sm text-red-500 hover:text-red-600 hover:bg-red-50 rounded-lg transition-colors"
>
<LucideIcon name="trash-2" size={14} />
Delete
</button>
{/* Delete — mobile */}
<button
type="button"
onClick={() => openConfirmDeleteCandidate(candidateId)}
className="md:hidden inline-flex items-center justify-center min-w-[44px] min-h-[44px] p-2 text-red-500 hover:text-red-600 hover:bg-red-50 rounded-lg transition-colors"
aria-label="Delete"
title="Delete"
>
<LucideIcon name="trash-2" size={16} />
</button>
</div>
)}
</div>