diff --git a/frontend/src/pages/xray/outbounds/OutboundFormModal.tsx b/frontend/src/pages/xray/outbounds/OutboundFormModal.tsx
index 6435ea48..aa009fb4 100644
--- a/frontend/src/pages/xray/outbounds/OutboundFormModal.tsx
+++ b/frontend/src/pages/xray/outbounds/OutboundFormModal.tsx
@@ -53,6 +53,7 @@ import {
MODE_OPTIONS,
NETWORK_OPTIONS,
PROTOCOL_OPTIONS,
+ SERVER_PROTOCOLS,
UTLS_OPTIONS,
} from './outbound-form-constants';
import {
@@ -61,9 +62,20 @@ import {
isMuxAllowed,
newStreamSlice,
} from './outbound-form-helpers';
-import { OutboundCoreProtocolFields } from './outbound-core-fields';
-import { WireguardOutboundFields } from './outbound-wireguard-fields';
-import { BlackholeFields, DnsFields, FreedomFields, LoopbackFields } from './protocols';
+import {
+ BlackholeFields,
+ DnsFields,
+ FreedomFields,
+ HttpFields,
+ LoopbackFields,
+ ServerTarget,
+ ShadowsocksFields,
+ SocksFields,
+ TrojanFields,
+ VlessFields,
+ VmessFields,
+ WireguardFields,
+} from './protocols';
import './OutboundFormModal.css';
// Pattern A rewrite of OutboundFormModal. Built as a sibling `.new.tsx`
@@ -388,7 +400,13 @@ export default function OutboundFormModal({
-
+ {SERVER_PROTOCOLS.has(protocol) && }
+ {protocol === 'vmess' && }
+ {protocol === 'vless' && }
+ {protocol === 'trojan' && }
+ {protocol === 'shadowsocks' && }
+ {protocol === 'http' && }
+ {protocol === 'socks' && }
{protocol === 'loopback' && }
{protocol === 'blackhole' && }
@@ -470,7 +488,7 @@ export default function OutboundFormModal({
)}
- {protocol === 'wireguard' && }
+ {protocol === 'wireguard' && }
{streamAllowed && network && (
<>
diff --git a/frontend/src/pages/xray/outbounds/outbound-core-fields.tsx b/frontend/src/pages/xray/outbounds/outbound-core-fields.tsx
deleted file mode 100644
index 8267e064..00000000
--- a/frontend/src/pages/xray/outbounds/outbound-core-fields.tsx
+++ /dev/null
@@ -1,125 +0,0 @@
-import { useTranslation } from 'react-i18next';
-import { Form, Input, InputNumber, Select, Switch } from 'antd';
-
-import {
- ShadowsocksOutboundFormSettingsSchema,
- TrojanOutboundFormSettingsSchema,
- VlessOutboundFormSettingsSchema,
- VmessOutboundFormSettingsSchema,
-} from '@/schemas/forms/outbound-form';
-import { SSMethodSchema } from '@/schemas/protocols/shared/shadowsocks';
-import { antdRule } from '@/utils/zodForm';
-
-import { SECURITY_OPTIONS, SERVER_PROTOCOLS, SS_METHOD_OPTIONS } from './outbound-form-constants';
-
-export function OutboundCoreProtocolFields({ protocol }: { protocol: string }) {
- const { t } = useTranslation();
- return (
- <>
- {/* Shared connect target (address + port) for protocols
- whose form schema carries them flat at settings root.
- Hidden for freedom/blackhole/dns/loopback/wireguard. */}
- {SERVER_PROTOCOLS.has(protocol) && (
- <>
-
-
-
-
-
-
- >
- )}
-
- {(protocol === 'vmess' || protocol === 'vless') && (
-
-
-
- )}
- {protocol === 'vmess' && (
-
-
-
- )}
- {protocol === 'vless' && (
- <>
-
-
-
-
-
-
- >
- )}
-
- {(protocol === 'trojan' || protocol === 'shadowsocks') && (
-
-
-
- )}
-
- {protocol === 'shadowsocks' && (
- <>
-
-
-
-
-
-
-
-
-
- >
- )}
-
- {(protocol === 'socks' || protocol === 'http') && (
- <>
-
-
-
-
-
-
- >
- )}
- >
- );
-}
diff --git a/frontend/src/pages/xray/outbounds/protocols/http.tsx b/frontend/src/pages/xray/outbounds/protocols/http.tsx
new file mode 100644
index 00000000..895f71f6
--- /dev/null
+++ b/frontend/src/pages/xray/outbounds/protocols/http.tsx
@@ -0,0 +1,16 @@
+import { useTranslation } from 'react-i18next';
+import { Form, Input } from 'antd';
+
+export default function HttpFields() {
+ const { t } = useTranslation();
+ return (
+ <>
+
+
+
+
+
+
+ >
+ );
+}
diff --git a/frontend/src/pages/xray/outbounds/protocols/index.ts b/frontend/src/pages/xray/outbounds/protocols/index.ts
index 54b7e4e6..dd90267b 100644
--- a/frontend/src/pages/xray/outbounds/protocols/index.ts
+++ b/frontend/src/pages/xray/outbounds/protocols/index.ts
@@ -1,3 +1,11 @@
+export { default as ServerTarget } from './server-target';
+export { default as VmessFields } from './vmess';
+export { default as VlessFields } from './vless';
+export { default as TrojanFields } from './trojan';
+export { default as ShadowsocksFields } from './shadowsocks';
+export { default as HttpFields } from './http';
+export { default as SocksFields } from './socks';
+export { default as WireguardFields } from './wireguard';
export { default as FreedomFields } from './freedom';
export { default as LoopbackFields } from './loopback';
export { default as BlackholeFields } from './blackhole';
diff --git a/frontend/src/pages/xray/outbounds/protocols/server-target.tsx b/frontend/src/pages/xray/outbounds/protocols/server-target.tsx
new file mode 100644
index 00000000..a89f9b50
--- /dev/null
+++ b/frontend/src/pages/xray/outbounds/protocols/server-target.tsx
@@ -0,0 +1,24 @@
+import { useTranslation } from 'react-i18next';
+import { Form, Input, InputNumber } from 'antd';
+
+export default function ServerTarget() {
+ const { t } = useTranslation();
+ return (
+ <>
+
+
+
+
+
+
+ >
+ );
+}
diff --git a/frontend/src/pages/xray/outbounds/protocols/shadowsocks.tsx b/frontend/src/pages/xray/outbounds/protocols/shadowsocks.tsx
new file mode 100644
index 00000000..aa40766b
--- /dev/null
+++ b/frontend/src/pages/xray/outbounds/protocols/shadowsocks.tsx
@@ -0,0 +1,40 @@
+import { useTranslation } from 'react-i18next';
+import { Form, Input, InputNumber, Select, Switch } from 'antd';
+
+import { ShadowsocksOutboundFormSettingsSchema } from '@/schemas/forms/outbound-form';
+import { SSMethodSchema } from '@/schemas/protocols/shared/shadowsocks';
+import { antdRule } from '@/utils/zodForm';
+
+import { SS_METHOD_OPTIONS } from '../outbound-form-constants';
+
+export default function ShadowsocksFields() {
+ const { t } = useTranslation();
+ return (
+ <>
+
+
+
+
+
+
+
+
+
+
+
+
+ >
+ );
+}
diff --git a/frontend/src/pages/xray/outbounds/protocols/socks.tsx b/frontend/src/pages/xray/outbounds/protocols/socks.tsx
new file mode 100644
index 00000000..51ff74cd
--- /dev/null
+++ b/frontend/src/pages/xray/outbounds/protocols/socks.tsx
@@ -0,0 +1,16 @@
+import { useTranslation } from 'react-i18next';
+import { Form, Input } from 'antd';
+
+export default function SocksFields() {
+ const { t } = useTranslation();
+ return (
+ <>
+
+
+
+
+
+
+ >
+ );
+}
diff --git a/frontend/src/pages/xray/outbounds/protocols/trojan.tsx b/frontend/src/pages/xray/outbounds/protocols/trojan.tsx
new file mode 100644
index 00000000..34d9a53e
--- /dev/null
+++ b/frontend/src/pages/xray/outbounds/protocols/trojan.tsx
@@ -0,0 +1,18 @@
+import { useTranslation } from 'react-i18next';
+import { Form, Input } from 'antd';
+
+import { TrojanOutboundFormSettingsSchema } from '@/schemas/forms/outbound-form';
+import { antdRule } from '@/utils/zodForm';
+
+export default function TrojanFields() {
+ const { t } = useTranslation();
+ return (
+
+
+
+ );
+}
diff --git a/frontend/src/pages/xray/outbounds/protocols/vless.tsx b/frontend/src/pages/xray/outbounds/protocols/vless.tsx
new file mode 100644
index 00000000..444a31c2
--- /dev/null
+++ b/frontend/src/pages/xray/outbounds/protocols/vless.tsx
@@ -0,0 +1,33 @@
+import { useTranslation } from 'react-i18next';
+import { Form, Input } from 'antd';
+
+import {
+ VlessOutboundFormSettingsSchema,
+ VmessOutboundFormSettingsSchema,
+} from '@/schemas/forms/outbound-form';
+import { antdRule } from '@/utils/zodForm';
+
+export default function VlessFields() {
+ const { t } = useTranslation();
+ return (
+ <>
+
+
+
+
+
+
+
+
+
+ >
+ );
+}
diff --git a/frontend/src/pages/xray/outbounds/protocols/vmess.tsx b/frontend/src/pages/xray/outbounds/protocols/vmess.tsx
new file mode 100644
index 00000000..78b17ae1
--- /dev/null
+++ b/frontend/src/pages/xray/outbounds/protocols/vmess.tsx
@@ -0,0 +1,29 @@
+import { useTranslation } from 'react-i18next';
+import { Form, Input, Select } from 'antd';
+
+import { VmessOutboundFormSettingsSchema } from '@/schemas/forms/outbound-form';
+import { antdRule } from '@/utils/zodForm';
+
+import { SECURITY_OPTIONS } from '../outbound-form-constants';
+
+export default function VmessFields() {
+ const { t } = useTranslation();
+ return (
+ <>
+
+
+
+
+
+
+ >
+ );
+}
diff --git a/frontend/src/pages/xray/outbounds/outbound-wireguard-fields.tsx b/frontend/src/pages/xray/outbounds/protocols/wireguard.tsx
similarity index 98%
rename from frontend/src/pages/xray/outbounds/outbound-wireguard-fields.tsx
rename to frontend/src/pages/xray/outbounds/protocols/wireguard.tsx
index c6a85aad..a143c188 100644
--- a/frontend/src/pages/xray/outbounds/outbound-wireguard-fields.tsx
+++ b/frontend/src/pages/xray/outbounds/protocols/wireguard.tsx
@@ -7,7 +7,7 @@ import { InputAddon } from '@/components/ui';
import { WireguardDomainStrategy } from '@/schemas/primitives';
import type { OutboundFormValues } from '@/schemas/forms/outbound-form';
-export function WireguardOutboundFields({ form }: { form: FormInstance }) {
+export default function WireguardFields({ form }: { form: FormInstance }) {
const { t } = useTranslation();
return (
<>