import React, { useState } from "react"; import { ChevronDownIcon, CheckmarkCircleIcon, EditIcon } from "@sanity/icons"; import { BulkDoc, RowEdit, scoreColor } from "./types"; import ScoreBar from "./ScoreBar"; /* eslint-disable @typescript-eslint/no-explicit-any */ interface Props { doc: BulkDoc; edit: RowEdit; isOpen: boolean; onToggleExpand: (id: string) => void; onToggleSelect: (id: string, e: React.MouseEvent | React.KeyboardEvent) => void; onFieldChange: (id: string, field: keyof Omit, val: string) => void; onSave: (doc: BulkDoc) => void; } const FIELD_INPUT: React.CSSProperties = { width: "100%", padding: "9px 12px", background: "var(--card-bg-color)", border: "1px solid var(--card-border-color)", borderRadius: 8, color: "var(--card-fg-color)", fontSize: 13, outline: "none", fontFamily: "inherit", boxSizing: "border-box", transition: "border-color 0.15s", }; const SECTION_HEADER: React.CSSProperties = { fontSize: 10, fontWeight: 700, color: "var(--card-muted-fg-color)", letterSpacing: 1.5, textTransform: "uppercase", marginBottom: 10, marginTop: 4, display: "flex", alignItems: "center", gap: 6, }; function CharBadge({ length, min, max }: { length: number; min: number; max: number }) { if (length === 0) return null; const ok = length >= min && length <= max; return ( {length} / {max} ); } function FieldBlock({ label, hint, required, children, }: { label: string; hint?: string; required?: boolean; children: React.ReactNode; }) { return (
{label} {required && *}
{children} {hint && (
{hint}
)}
); } export default function BulkDocRow({ doc, edit, isOpen, onToggleExpand, onToggleSelect, onFieldChange, onSave, }: Props) { const [hovered, setHovered] = useState(false); const handleChange = (field: keyof Omit) => (e: React.ChangeEvent) => { onFieldChange(doc._id, field, e.target.value); }; const issueCount = doc.issues.length; const color = scoreColor(doc.score); return (
setHovered(true)} onMouseLeave={() => setHovered(false)} >
onToggleExpand(doc._id)} onKeyDown={(e) => e.key === "Enter" && onToggleExpand(doc._id)} style={{ display: "grid", gridTemplateColumns: "36px 100px 1fr auto auto 32px", gap: 16, alignItems: "center", padding: "12px 16px", cursor: "pointer", }} >
onToggleSelect(doc._id, e as any)} onClick={(e) => e.stopPropagation()} style={{ cursor: "pointer", accentColor: "var(--card-link-color)" }} />
{doc.docTitle}
{edit.metaTitle && edit.metaTitle !== doc.docTitle && (
{edit.metaTitle}
)}
{doc._type}
{issueCount === 0 ? "Good" : `${issueCount} issue${issueCount !== 1 ? "s" : ""}`}
{isOpen && (
{issueCount > 0 && (
{doc.issues.map((issue) => ( {issue} ))}
)}
Edit SEO Fields — {doc.docTitle}
Core SEO
Ideal: 50–60 characters