fix: improve expertise input handling to prevent character loss during comma-separated editing
This commit is contained in:
@@ -143,6 +143,48 @@ function emptyStatItem(): StatItem {
|
||||
const inputCls = 'w-full px-3 py-2 border border-[#e5e7eb] rounded-xl focus:outline-none focus:border-[#f5a623] text-[#00293d] bg-white placeholder:text-[#666666]';
|
||||
const textareaCls = inputCls;
|
||||
|
||||
// Expertise input keeps its own raw-text state so the user can type commas
|
||||
// without the display being destructively re-derived from the parsed array
|
||||
// (which was dropping trailing commas mid-typing and merging new tokens into
|
||||
// the previous one).
|
||||
function ExpertiseInput({
|
||||
value,
|
||||
onChange,
|
||||
}: {
|
||||
value: string[];
|
||||
onChange: (next: string[]) => void;
|
||||
}) {
|
||||
const [raw, setRaw] = useState<string>(() => value.join(', '));
|
||||
|
||||
useEffect(() => {
|
||||
const currentParsed = raw.split(',').map((s) => s.trim()).filter(Boolean);
|
||||
const matches =
|
||||
currentParsed.length === value.length &&
|
||||
currentParsed.every((v, i) => v === value[i]);
|
||||
if (!matches) setRaw(value.join(', '));
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [value]);
|
||||
|
||||
return (
|
||||
<input
|
||||
type="text"
|
||||
className={inputCls}
|
||||
value={raw}
|
||||
onChange={(e) => {
|
||||
const next = e.target.value;
|
||||
setRaw(next);
|
||||
onChange(next.split(',').map((s) => s.trim()).filter(Boolean));
|
||||
}}
|
||||
onBlur={() => {
|
||||
const parsed = raw.split(',').map((s) => s.trim()).filter(Boolean);
|
||||
setRaw(parsed.join(', '));
|
||||
onChange(parsed);
|
||||
}}
|
||||
placeholder="Expertise (comma-separated)"
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Page component
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -828,7 +870,7 @@ export default function CmsPage() {
|
||||
<input type="text" className={inputCls} value={item.location} onChange={(e) => updateItem(idx, { location: e.target.value })} placeholder="Location" />
|
||||
<input type="text" className={inputCls} value={item.experience} onChange={(e) => updateItem(idx, { experience: e.target.value })} placeholder="Experience" />
|
||||
</div>
|
||||
<input type="text" className={inputCls} value={item.expertise.join(', ')} onChange={(e) => updateItem(idx, { expertise: e.target.value.split(',').map((s) => s.trim()).filter(Boolean) })} placeholder="Expertise (comma-separated)" />
|
||||
<ExpertiseInput value={item.expertise} onChange={(next) => updateItem(idx, { expertise: next })} />
|
||||
<input type="text" className={inputCls} value={item.imageUrl} onChange={(e) => updateItem(idx, { imageUrl: e.target.value })} placeholder="Image URL" />
|
||||
</div>
|
||||
))}
|
||||
|
||||
Reference in New Issue
Block a user