Files
João Salavisa 5257dfbaab fix(web): close the i18n coverage gaps in the non-JSX scanner and locale catalogs (#2727)
Co-authored-by: Kandev Agent <agent@kandev.dev>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-16 23:03:29 +00:00

68 lines
2.0 KiB
TypeScript

"use client";
import { IconPlus, IconX } from "@tabler/icons-react";
import { Button } from "@kandev/ui/button";
import { Input } from "@kandev/ui/input";
import type { KeyValue } from "@/lib/settings/types";
import { generateUUID } from "@/lib/utils";
import { t } from "@/lib/i18n";
type KeyValueInputProps = {
items: KeyValue[];
onChange: (items: KeyValue[]) => void;
keyPlaceholder?: string;
valuePlaceholder?: string;
addButtonLabel?: string;
masked?: boolean;
};
export function KeyValueInput({
items,
onChange,
keyPlaceholder = t("settings:keyValueKeyPlaceholder"),
valuePlaceholder = t("settings:keyValueValuePlaceholder"),
addButtonLabel = t("settings:keyValueAddItem"),
masked = false,
}: KeyValueInputProps) {
const handleAdd = () => {
onChange([...items, { id: generateUUID(), key: "", value: "" }]);
};
const handleRemove = (id: string) => {
onChange(items.filter((item) => item.id !== id));
};
const handleChange = (id: string, field: "key" | "value", value: string) => {
onChange(items.map((item) => (item.id === id ? { ...item, [field]: value } : item)));
};
return (
<div className="space-y-2">
{items.map((item) => (
<div key={item.id} className="flex gap-2">
<Input
placeholder={keyPlaceholder}
value={item.key}
onChange={(e) => handleChange(item.id, "key", e.target.value)}
className="flex-1"
/>
<Input
type={masked ? "password" : "text"}
placeholder={valuePlaceholder}
value={item.value}
onChange={(e) => handleChange(item.id, "value", e.target.value)}
className="flex-1"
/>
<Button variant="ghost" size="icon" onClick={() => handleRemove(item.id)}>
<IconX className="h-4 w-4" />
</Button>
</div>
))}
<Button variant="outline" size="sm" onClick={handleAdd} className="w-full">
<IconPlus className="h-4 w-4 mr-2" />
{addButtonLabel}
</Button>
</div>
);
}