mirror of
https://github.com/farion1231/cc-switch.git
synced 2026-08-01 12:22:09 +08:00
refactor(usage): simplify usage script modal UI
- Remove redundant "Request Configuration" section (URL, method, headers, body editors) - Move timeout and auto query interval fields to preset template section - Simplify "Enable usage query" toggle styling - Remove redundant hints and variables description - Add i18n support for Base URL label - Include "0 to disable" hint directly in auto interval label
This commit is contained in:
@@ -349,14 +349,9 @@ const UsageScriptModal: React.FC<UsageScriptModalProps> = ({
|
|||||||
footer={footer}
|
footer={footer}
|
||||||
>
|
>
|
||||||
<div className="glass rounded-xl border border-white/10 px-6 py-4 flex items-center justify-between gap-4">
|
<div className="glass rounded-xl border border-white/10 px-6 py-4 flex items-center justify-between gap-4">
|
||||||
<div className="space-y-1">
|
<p className="text-base font-medium leading-none text-foreground">
|
||||||
<p className="text-sm font-medium leading-none text-foreground">
|
{t("usageScript.enableUsageQuery")}
|
||||||
{t("usageScript.enableUsageQuery")}
|
</p>
|
||||||
</p>
|
|
||||||
<p className="text-xs text-muted-foreground">
|
|
||||||
{t("usageScript.autoQueryIntervalHint")}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<Switch
|
<Switch
|
||||||
checked={script.enabled}
|
checked={script.enabled}
|
||||||
onCheckedChange={(checked) =>
|
onCheckedChange={(checked) =>
|
||||||
@@ -370,14 +365,9 @@ const UsageScriptModal: React.FC<UsageScriptModalProps> = ({
|
|||||||
<div className="space-y-6">
|
<div className="space-y-6">
|
||||||
{/* 预设模板选择 */}
|
{/* 预设模板选择 */}
|
||||||
<div className="space-y-4 glass rounded-xl border border-white/10 p-6">
|
<div className="space-y-4 glass rounded-xl border border-white/10 p-6">
|
||||||
<div className="flex flex-wrap items-center justify-between gap-2">
|
<Label className="text-base font-medium">
|
||||||
<Label className="text-base font-medium">
|
{t("usageScript.presetTemplate")}
|
||||||
{t("usageScript.presetTemplate")}
|
</Label>
|
||||||
</Label>
|
|
||||||
<span className="text-xs text-muted-foreground">
|
|
||||||
{t("usageScript.variablesHint")}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div className="flex gap-2 flex-wrap">
|
<div className="flex gap-2 flex-wrap">
|
||||||
{Object.keys(PRESET_TEMPLATES).map((name) => {
|
{Object.keys(PRESET_TEMPLATES).map((name) => {
|
||||||
const isSelected = selectedTemplate === name;
|
const isSelected = selectedTemplate === name;
|
||||||
@@ -447,7 +437,9 @@ const UsageScriptModal: React.FC<UsageScriptModalProps> = ({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Label htmlFor="usage-base-url">Base URL</Label>
|
<Label htmlFor="usage-base-url">
|
||||||
|
{t("usageScript.baseUrl")}
|
||||||
|
</Label>
|
||||||
<Input
|
<Input
|
||||||
id="usage-base-url"
|
id="usage-base-url"
|
||||||
type="text"
|
type="text"
|
||||||
@@ -466,7 +458,9 @@ const UsageScriptModal: React.FC<UsageScriptModalProps> = ({
|
|||||||
{selectedTemplate === TEMPLATE_KEYS.NEW_API && (
|
{selectedTemplate === TEMPLATE_KEYS.NEW_API && (
|
||||||
<>
|
<>
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Label htmlFor="usage-newapi-base-url">Base URL</Label>
|
<Label htmlFor="usage-newapi-base-url">
|
||||||
|
{t("usageScript.baseUrl")}
|
||||||
|
</Label>
|
||||||
<Input
|
<Input
|
||||||
id="usage-newapi-base-url"
|
id="usage-newapi-base-url"
|
||||||
type="text"
|
type="text"
|
||||||
@@ -545,141 +539,36 @@ const UsageScriptModal: React.FC<UsageScriptModalProps> = ({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* 脚本配置 */}
|
{/* 通用配置(始终显示) */}
|
||||||
<div className="space-y-4 glass rounded-xl border border-white/10 p-6">
|
<div className="grid gap-4 md:grid-cols-2 pt-4 border-t border-white/10">
|
||||||
<div className="flex items-center justify-between">
|
{/* 超时时间 */}
|
||||||
<h4 className="text-base font-medium text-foreground">
|
|
||||||
{t("usageScript.scriptConfig")}
|
|
||||||
</h4>
|
|
||||||
<p className="text-xs text-muted-foreground">
|
|
||||||
{t("usageScript.variablesHint")}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="grid gap-4">
|
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Label htmlFor="usage-request-url">
|
<Label htmlFor="usage-timeout">
|
||||||
{t("usageScript.requestUrl")}
|
{t("usageScript.timeoutSeconds")}
|
||||||
</Label>
|
</Label>
|
||||||
<Input
|
<Input
|
||||||
id="usage-request-url"
|
id="usage-timeout"
|
||||||
type="text"
|
type="number"
|
||||||
value={script.request?.url || ""}
|
min={0}
|
||||||
onChange={(e) => {
|
value={script.timeout ?? 10}
|
||||||
|
onChange={(e) =>
|
||||||
setScript({
|
setScript({
|
||||||
...script,
|
...script,
|
||||||
request: { ...script.request, url: e.target.value },
|
timeout: validateTimeout(e.target.value),
|
||||||
});
|
})
|
||||||
}}
|
}
|
||||||
placeholder={t("usageScript.requestUrlPlaceholder")}
|
onBlur={(e) =>
|
||||||
|
setScript({
|
||||||
|
...script,
|
||||||
|
timeout: validateTimeout(e.target.value),
|
||||||
|
})
|
||||||
|
}
|
||||||
className="border-white/10"
|
className="border-white/10"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-4">
|
{/* 自动查询间隔 */}
|
||||||
<div className="space-y-2">
|
|
||||||
<Label htmlFor="usage-method">
|
|
||||||
{t("usageScript.method")}
|
|
||||||
</Label>
|
|
||||||
<Input
|
|
||||||
id="usage-method"
|
|
||||||
type="text"
|
|
||||||
value={script.request?.method || "GET"}
|
|
||||||
onChange={(e) => {
|
|
||||||
setScript({
|
|
||||||
...script,
|
|
||||||
request: {
|
|
||||||
...script.request,
|
|
||||||
method: e.target.value.toUpperCase(),
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
placeholder="GET / POST"
|
|
||||||
className="border-white/10"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="space-y-2">
|
|
||||||
<Label htmlFor="usage-timeout">
|
|
||||||
{t("usageScript.timeoutSeconds")}
|
|
||||||
</Label>
|
|
||||||
<Input
|
|
||||||
id="usage-timeout"
|
|
||||||
type="number"
|
|
||||||
min={0}
|
|
||||||
value={script.timeout ?? 10}
|
|
||||||
onChange={(e) =>
|
|
||||||
setScript({
|
|
||||||
...script,
|
|
||||||
timeout: validateTimeout(e.target.value),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
onBlur={(e) =>
|
|
||||||
setScript({
|
|
||||||
...script,
|
|
||||||
timeout: validateTimeout(e.target.value),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
className="border-white/10"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="space-y-2">
|
|
||||||
<Label htmlFor="usage-headers">
|
|
||||||
{t("usageScript.headers")}
|
|
||||||
</Label>
|
|
||||||
<JsonEditor
|
|
||||||
id="usage-headers"
|
|
||||||
value={
|
|
||||||
script.request?.headers
|
|
||||||
? JSON.stringify(script.request.headers, null, 2)
|
|
||||||
: "{}"
|
|
||||||
}
|
|
||||||
onChange={(value) => {
|
|
||||||
try {
|
|
||||||
const parsed = JSON.parse(value || "{}");
|
|
||||||
setScript({
|
|
||||||
...script,
|
|
||||||
request: { ...script.request, headers: parsed },
|
|
||||||
});
|
|
||||||
} catch (error) {
|
|
||||||
console.error("Invalid headers JSON", error);
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
height={180}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="space-y-2">
|
|
||||||
<Label htmlFor="usage-body">{t("usageScript.body")}</Label>
|
|
||||||
<JsonEditor
|
|
||||||
id="usage-body"
|
|
||||||
value={
|
|
||||||
script.request?.body
|
|
||||||
? JSON.stringify(script.request.body, null, 2)
|
|
||||||
: "{}"
|
|
||||||
}
|
|
||||||
onChange={(value) => {
|
|
||||||
try {
|
|
||||||
const parsed =
|
|
||||||
value?.trim() === "" ? undefined : JSON.parse(value);
|
|
||||||
setScript({
|
|
||||||
...script,
|
|
||||||
request: { ...script.request, body: parsed },
|
|
||||||
});
|
|
||||||
} catch (error) {
|
|
||||||
toast.error(
|
|
||||||
t("usageScript.invalidJson") || "Body 必须是合法 JSON",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
height={220}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Label htmlFor="usage-interval">
|
<Label htmlFor="usage-interval">
|
||||||
{t("usageScript.autoIntervalMinutes")}
|
{t("usageScript.autoIntervalMinutes")}
|
||||||
@@ -708,9 +597,6 @@ const UsageScriptModal: React.FC<UsageScriptModalProps> = ({
|
|||||||
}
|
}
|
||||||
className="border-white/10"
|
className="border-white/10"
|
||||||
/>
|
/>
|
||||||
<p className="text-xs text-muted-foreground">
|
|
||||||
{t("usageScript.autoQueryIntervalHint")}
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -376,6 +376,7 @@
|
|||||||
"templateGeneral": "General",
|
"templateGeneral": "General",
|
||||||
"templateNewAPI": "NewAPI",
|
"templateNewAPI": "NewAPI",
|
||||||
"credentialsConfig": "Credentials",
|
"credentialsConfig": "Credentials",
|
||||||
|
"baseUrl": "Base URL",
|
||||||
"accessToken": "Access Token",
|
"accessToken": "Access Token",
|
||||||
"accessTokenPlaceholder": "Generate in 'Security Settings'",
|
"accessTokenPlaceholder": "Generate in 'Security Settings'",
|
||||||
"userId": "User ID",
|
"userId": "User ID",
|
||||||
@@ -389,7 +390,7 @@
|
|||||||
"timeoutHint": "Range: 2-30 seconds",
|
"timeoutHint": "Range: 2-30 seconds",
|
||||||
"timeoutMustBeInteger": "Timeout must be an integer, decimal part ignored",
|
"timeoutMustBeInteger": "Timeout must be an integer, decimal part ignored",
|
||||||
"timeoutCannotBeNegative": "Timeout cannot be negative",
|
"timeoutCannotBeNegative": "Timeout cannot be negative",
|
||||||
"autoIntervalMinutes": "Auto query interval (minutes)",
|
"autoIntervalMinutes": "Auto query interval (minutes, 0 to disable)",
|
||||||
"autoQueryInterval": "Auto Query Interval (minutes)",
|
"autoQueryInterval": "Auto Query Interval (minutes)",
|
||||||
"autoQueryIntervalHint": "0 to disable; recommend 5-60 minutes",
|
"autoQueryIntervalHint": "0 to disable; recommend 5-60 minutes",
|
||||||
"intervalMustBeInteger": "Interval must be an integer, decimal part ignored",
|
"intervalMustBeInteger": "Interval must be an integer, decimal part ignored",
|
||||||
|
|||||||
@@ -376,7 +376,8 @@
|
|||||||
"templateGeneral": "通用模板",
|
"templateGeneral": "通用模板",
|
||||||
"templateNewAPI": "NewAPI",
|
"templateNewAPI": "NewAPI",
|
||||||
"credentialsConfig": "凭证配置",
|
"credentialsConfig": "凭证配置",
|
||||||
"accessToken": "访问令牌",
|
"baseUrl": "请求地址",
|
||||||
|
"accessToken": "访问令牌(在个人安全设置里获取)",
|
||||||
"accessTokenPlaceholder": "在'安全设置'里生成",
|
"accessTokenPlaceholder": "在'安全设置'里生成",
|
||||||
"userId": "用户 ID",
|
"userId": "用户 ID",
|
||||||
"userIdPlaceholder": "例如:114514",
|
"userIdPlaceholder": "例如:114514",
|
||||||
@@ -389,7 +390,7 @@
|
|||||||
"timeoutHint": "范围: 2-30 秒",
|
"timeoutHint": "范围: 2-30 秒",
|
||||||
"timeoutMustBeInteger": "超时时间必须为整数,小数部分已忽略",
|
"timeoutMustBeInteger": "超时时间必须为整数,小数部分已忽略",
|
||||||
"timeoutCannotBeNegative": "超时时间不能为负数",
|
"timeoutCannotBeNegative": "超时时间不能为负数",
|
||||||
"autoIntervalMinutes": "自动查询间隔(分钟)",
|
"autoIntervalMinutes": "自动查询间隔(分钟,0 表示不自动查询)",
|
||||||
"autoQueryInterval": "自动查询间隔(分钟)",
|
"autoQueryInterval": "自动查询间隔(分钟)",
|
||||||
"autoQueryIntervalHint": "0 表示不自动查询,建议 5-60 分钟",
|
"autoQueryIntervalHint": "0 表示不自动查询,建议 5-60 分钟",
|
||||||
"intervalMustBeInteger": "自动查询间隔必须为整数,小数部分已忽略",
|
"intervalMustBeInteger": "自动查询间隔必须为整数,小数部分已忽略",
|
||||||
|
|||||||
Reference in New Issue
Block a user