Files
GEOAgentArticleOptimizer/src/components/fact-card-editor.tsx
T

134 lines
3.3 KiB
TypeScript

"use client";
import type { CandidateFactCard, ConfirmedFactCard } from "../lib/domain/types";
interface FactCardEditorProps {
factCard: CandidateFactCard | null;
isSaving: boolean;
onChange: (factCard: CandidateFactCard) => void;
onConfirm: () => void;
}
const listFields = [
"company_short_names",
"brand_names",
"product_names",
"core_claims",
"forbidden_claims",
"image_topics",
"uncertain_items",
] as const;
export function FactCardEditor({
factCard,
isSaving,
onChange,
onConfirm,
}: FactCardEditorProps) {
if (!factCard) {
return (
<section className="panel empty-panel">
<div className="panel-heading">Fact Card</div>
</section>
);
}
const currentFactCard = factCard;
const canOptimize = currentFactCard.uncertain_items.length === 0;
function update<K extends keyof CandidateFactCard>(
key: K,
value: CandidateFactCard[K],
) {
onChange({
...currentFactCard,
[key]: value,
is_ready_for_optimization:
key === "uncertain_items"
? (value as string[]).length === 0
: currentFactCard.uncertain_items.length === 0,
});
}
return (
<section className="panel stack">
<div className="panel-heading">
<span>Fact Card</span>
<button disabled={!canOptimize || isSaving} onClick={onConfirm}>
{isSaving ? "Saving..." : "Confirm"}
</button>
</div>
<label>
<span>Company full name</span>
<input
value={factCard.company_full_name}
onChange={(event) => update("company_full_name", event.target.value)}
/>
</label>
<div className="two-col">
<label>
<span>Target industry</span>
<input
value={factCard.target_industry}
onChange={(event) => update("target_industry", event.target.value)}
/>
</label>
<label>
<span>Target audience</span>
<input
value={factCard.target_audience}
onChange={(event) => update("target_audience", event.target.value)}
/>
</label>
</div>
<label>
<span>Experience years</span>
<input
min="0"
type="number"
value={factCard.experience_years ?? ""}
onChange={(event) =>
update(
"experience_years",
event.target.value ? Number(event.target.value) : null,
)
}
/>
</label>
{listFields.map((field) => (
<label key={field}>
<span>{field.replace(/_/g, " ")}</span>
<textarea
value={factCard[field].join("\n")}
onChange={(event) =>
update(
field,
event.target.value
.split(/\r?\n/)
.map((line) => line.trim())
.filter(Boolean) as CandidateFactCard[typeof field],
)
}
/>
</label>
))}
{!canOptimize && (
<p className="status-text fail">
Resolve uncertain items before optimization.
</p>
)}
</section>
);
}
export function toConfirmedFactCard(
factCard: CandidateFactCard,
): ConfirmedFactCard {
return {
...factCard,
uncertain_items: [],
is_ready_for_optimization: true,
confirmed_by_user: true,
};
}