feat(08-01): create StatusBadge component and wire into CandidateCard

- StatusBadge: clickable pill badge with popup menu (researching/ordered/arrived)
- Muted gray styling, LucideIcon per status, click-outside dismiss, Escape key support
- CandidateCard: status + onStatusChange props, StatusBadge in pill row after category
- Thread detail page: passes candidate.status and useUpdateCandidate for onStatusChange
- Fix Biome formatting for candidateStatusSchema enum

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-16 14:12:02 +01:00
parent 5f89acd503
commit 25956ed3ee
4 changed files with 123 additions and 1 deletions

View File

@@ -2,6 +2,7 @@ import { useWeightUnit } from "../hooks/useWeightUnit";
import { formatPrice, formatWeight } from "../lib/formatters";
import { LucideIcon } from "../lib/iconData";
import { useUIStore } from "../stores/uiStore";
import { StatusBadge } from "./StatusBadge";
interface CandidateCardProps {
id: number;
@@ -14,6 +15,8 @@ interface CandidateCardProps {
productUrl?: string | null;
threadId: number;
isActive: boolean;
status: "researching" | "ordered" | "arrived";
onStatusChange: (status: "researching" | "ordered" | "arrived") => void;
}
export function CandidateCard({
@@ -27,6 +30,8 @@ export function CandidateCard({
productUrl,
threadId,
isActive,
status,
onStatusChange,
}: CandidateCardProps) {
const unit = useWeightUnit();
const openCandidateEditPanel = useUIStore((s) => s.openCandidateEditPanel);
@@ -106,6 +111,7 @@ export function CandidateCard({
/>{" "}
{categoryName}
</span>
<StatusBadge status={status} onStatusChange={onStatusChange} />
</div>
<div className="flex gap-2">
<button