feat(12-01): wire compare toggle and ComparisonTable into thread detail
- Extend uiStore candidateViewMode union to include "compare" value - Add columns-3 compare toggle button, shown only when thread has 2+ candidates - Hide "Add Candidate" button when in compare view (read-only intent) - Import and render ComparisonTable when candidateViewMode === "compare" - Pass displayItems so compare view reflects any pending reorder state - Existing list/grid views unchanged; all 135 tests pass
This commit is contained in:
@@ -3,6 +3,7 @@ import { Reorder } from "framer-motion";
|
|||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { CandidateCard } from "../../components/CandidateCard";
|
import { CandidateCard } from "../../components/CandidateCard";
|
||||||
import { CandidateListItem } from "../../components/CandidateListItem";
|
import { CandidateListItem } from "../../components/CandidateListItem";
|
||||||
|
import { ComparisonTable } from "../../components/ComparisonTable";
|
||||||
import {
|
import {
|
||||||
useReorderCandidates,
|
useReorderCandidates,
|
||||||
useUpdateCandidate,
|
useUpdateCandidate,
|
||||||
@@ -120,7 +121,7 @@ function ThreadDetailPage() {
|
|||||||
|
|
||||||
{/* Toolbar: Add candidate + view toggle */}
|
{/* Toolbar: Add candidate + view toggle */}
|
||||||
<div className="mb-6 flex items-center gap-3">
|
<div className="mb-6 flex items-center gap-3">
|
||||||
{isActive && (
|
{isActive && candidateViewMode !== "compare" && (
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={openCandidateAddPanel}
|
onClick={openCandidateAddPanel}
|
||||||
@@ -168,6 +169,20 @@ function ThreadDetailPage() {
|
|||||||
>
|
>
|
||||||
<LucideIcon name="layout-grid" size={16} />
|
<LucideIcon name="layout-grid" size={16} />
|
||||||
</button>
|
</button>
|
||||||
|
{thread.candidates.length >= 2 && (
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={() => setCandidateViewMode("compare")}
|
||||||
|
className={`p-1.5 rounded-md transition-colors ${
|
||||||
|
candidateViewMode === "compare"
|
||||||
|
? "bg-gray-200 text-gray-900"
|
||||||
|
: "text-gray-400 hover:text-gray-600"
|
||||||
|
}`}
|
||||||
|
title="Compare view"
|
||||||
|
>
|
||||||
|
<LucideIcon name="columns-3" size={16} />
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@@ -189,6 +204,11 @@ function ThreadDetailPage() {
|
|||||||
Add your first candidate to start comparing.
|
Add your first candidate to start comparing.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
) : candidateViewMode === "compare" ? (
|
||||||
|
<ComparisonTable
|
||||||
|
candidates={displayItems}
|
||||||
|
resolvedCandidateId={thread.resolvedCandidateId}
|
||||||
|
/>
|
||||||
) : candidateViewMode === "list" ? (
|
) : candidateViewMode === "list" ? (
|
||||||
isActive ? (
|
isActive ? (
|
||||||
<Reorder.Group
|
<Reorder.Group
|
||||||
|
|||||||
@@ -50,8 +50,8 @@ interface UIState {
|
|||||||
closeExternalLink: () => void;
|
closeExternalLink: () => void;
|
||||||
|
|
||||||
// Candidate view mode
|
// Candidate view mode
|
||||||
candidateViewMode: "list" | "grid";
|
candidateViewMode: "list" | "grid" | "compare";
|
||||||
setCandidateViewMode: (mode: "list" | "grid") => void;
|
setCandidateViewMode: (mode: "list" | "grid" | "compare") => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useUIStore = create<UIState>((set) => ({
|
export const useUIStore = create<UIState>((set) => ({
|
||||||
|
|||||||
Reference in New Issue
Block a user