mirror of
https://github.com/sqlchat/sqlchat.git
synced 2025-09-27 01:56:16 +08:00
feat: implement TextField kit component
This commit is contained in:
@ -9,6 +9,7 @@ import Select from "./kit/Select";
|
||||
import Icon from "./Icon";
|
||||
import DataStorageBanner from "./DataStorageBanner";
|
||||
import ActionConfirmModal from "./ActionConfirmModal";
|
||||
import TextField from "./kit/TextField";
|
||||
|
||||
interface Props {
|
||||
show: boolean;
|
||||
@ -219,7 +220,7 @@ const CreateConnectionModal = (props: Props) => {
|
||||
<div className="w-full flex flex-col">
|
||||
<label className="block text-sm font-medium text-gray-700 mb-1">Database Type</label>
|
||||
<Select
|
||||
className="w-full px-4 py-3"
|
||||
className="w-full"
|
||||
value={connection.engineType}
|
||||
itemList={[
|
||||
{ value: Engine.MySQL, label: "MySQL" },
|
||||
@ -230,54 +231,36 @@ const CreateConnectionModal = (props: Props) => {
|
||||
</div>
|
||||
<div className="w-full flex flex-col">
|
||||
<label className="block text-sm font-medium text-gray-700 mb-1">Host</label>
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Connect host"
|
||||
className="input input-bordered w-full"
|
||||
value={connection.host}
|
||||
onChange={(e) => setPartialConnection({ host: e.target.value })}
|
||||
/>
|
||||
<TextField placeholder="Connect host" value={connection.host} onChange={(value) => setPartialConnection({ host: value })} />
|
||||
</div>
|
||||
<div className="w-full flex flex-col">
|
||||
<label className="block text-sm font-medium text-gray-700 mb-1">Port</label>
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Connect port"
|
||||
className="input input-bordered w-full"
|
||||
value={connection.port}
|
||||
onChange={(e) => setPartialConnection({ port: e.target.value })}
|
||||
/>
|
||||
<TextField placeholder="Connect port" value={connection.port} onChange={(value) => setPartialConnection({ port: value })} />
|
||||
</div>
|
||||
{showDatabaseField && (
|
||||
<div className="w-full flex flex-col">
|
||||
<label className="block text-sm font-medium text-gray-700 mb-1">Database Name</label>
|
||||
<input
|
||||
type="text"
|
||||
<TextField
|
||||
placeholder="Connect database"
|
||||
className="input input-bordered w-full"
|
||||
value={connection.database}
|
||||
onChange={(e) => setPartialConnection({ database: e.target.value })}
|
||||
value={connection.database || ""}
|
||||
onChange={(value) => setPartialConnection({ database: value })}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<div className="w-full flex flex-col">
|
||||
<label className="block text-sm font-medium text-gray-700 mb-1">Username</label>
|
||||
<input
|
||||
type="text"
|
||||
<TextField
|
||||
placeholder="Connect username"
|
||||
className="input input-bordered w-full"
|
||||
value={connection.username}
|
||||
onChange={(e) => setPartialConnection({ username: e.target.value })}
|
||||
value={connection.username || ""}
|
||||
onChange={(value) => setPartialConnection({ username: value })}
|
||||
/>
|
||||
</div>
|
||||
<div className="w-full flex flex-col">
|
||||
<label className="block text-sm font-medium text-gray-700 mb-1">Password</label>
|
||||
<input
|
||||
type="text"
|
||||
<TextField
|
||||
placeholder="Connect password"
|
||||
className="input input-bordered w-full"
|
||||
value={connection.password}
|
||||
onChange={(e) => setPartialConnection({ password: e.target.value })}
|
||||
value={connection.password || ""}
|
||||
onChange={(value) => setPartialConnection({ password: value })}
|
||||
/>
|
||||
</div>
|
||||
<div className="w-full flex flex-col">
|
||||
|
@ -4,6 +4,7 @@ import { useTranslation } from "react-i18next";
|
||||
import { useConversationStore } from "@/store";
|
||||
import { Conversation } from "@/types";
|
||||
import Icon from "./Icon";
|
||||
import TextField from "./kit/TextField";
|
||||
|
||||
interface Props {
|
||||
conversation: Conversation;
|
||||
@ -38,13 +39,7 @@ const EditConversationTitleModal = (props: Props) => {
|
||||
<Icon.IoMdClose className="w-5 h-auto" />
|
||||
</button>
|
||||
<div className="w-full flex flex-col justify-start items-start space-y-3 pt-4">
|
||||
<input
|
||||
type="text"
|
||||
placeholder={t("conversation.conversation-title") || ""}
|
||||
className="input input-bordered w-full"
|
||||
value={title}
|
||||
onChange={(e) => setTitle(e.target.value)}
|
||||
/>
|
||||
<TextField placeholder={t("conversation.conversation-title") || ""} value={title} onChange={(value) => setTitle(value)} />
|
||||
</div>
|
||||
<div className="modal-action">
|
||||
<button className="btn btn-outline" onClick={close}>
|
||||
|
@ -3,6 +3,7 @@ import { useTranslation } from "react-i18next";
|
||||
import { useDebounce } from "react-use";
|
||||
import { useSettingStore } from "@/store";
|
||||
import { OpenAIApiConfig } from "@/types";
|
||||
import TextField from "./kit/TextField";
|
||||
|
||||
const OpenAIApiConfigView = () => {
|
||||
const { t } = useTranslation();
|
||||
@ -29,33 +30,19 @@ const OpenAIApiConfigView = () => {
|
||||
<h3 className="pl-4 text-sm text-gray-500">{t("setting.openai-api-configuration.self")}</h3>
|
||||
<div className="w-full border border-gray-200 p-4 rounded-lg">
|
||||
<div className="flex flex-col">
|
||||
<label htmlFor="openai-api-key">Key</label>
|
||||
<input
|
||||
id="openai-api-key"
|
||||
className="input input-bordered input-sm mt-1"
|
||||
type="text"
|
||||
<label className="mb-1">Key</label>
|
||||
<TextField
|
||||
placeholder="OpenAI API Key"
|
||||
value={openAIApiConfig.key}
|
||||
onChange={(e) => {
|
||||
handleSetOpenAIApiConfig({
|
||||
key: e.target.value,
|
||||
});
|
||||
}}
|
||||
onChange={(value) => handleSetOpenAIApiConfig({ key: value })}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-col mt-2">
|
||||
<label htmlFor="openai-api-endpoint">Endpoint</label>
|
||||
<input
|
||||
id="openai-api-endpoint"
|
||||
className="input input-bordered input-sm mt-1"
|
||||
type="text"
|
||||
<label className="mb-1">Endpoint</label>
|
||||
<TextField
|
||||
placeholder="OpenAI API Endpoint"
|
||||
value={openAIApiConfig.endpoint}
|
||||
onChange={(e) => {
|
||||
handleSetOpenAIApiConfig({
|
||||
endpoint: e.target.value,
|
||||
});
|
||||
}}
|
||||
onChange={(value) => handleSetOpenAIApiConfig({ endpoint: value })}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
24
src/components/kit/TextField.tsx
Normal file
24
src/components/kit/TextField.tsx
Normal file
@ -0,0 +1,24 @@
|
||||
interface Props {
|
||||
value: string;
|
||||
onChange: (value: string) => void;
|
||||
className?: string;
|
||||
disabled?: boolean;
|
||||
placeholder?: string;
|
||||
}
|
||||
|
||||
const TextField = (props: Props) => {
|
||||
const { value, disabled, className, placeholder, onChange } = props;
|
||||
|
||||
return (
|
||||
<input
|
||||
className={`${className || ""} w-full border px-3 py-2 rounded-lg`}
|
||||
type="text"
|
||||
disabled={disabled}
|
||||
placeholder={placeholder}
|
||||
value={value}
|
||||
onChange={(e) => onChange(e.target.value)}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default TextField;
|
Reference in New Issue
Block a user