2026-01-26 00:31:12 +08:00

153 lines
4.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { useState, ReactNode } from 'react';
import { validateNodeConfig } from '../utils/wireguardConfig';
import './NodeEditor.css';
interface NodeData {
label: string;
ipAddress: string;
listenPort: string;
privateKey: string;
publicKey: string;
endpoint?: string;
dnsServers?: string;
persistentKeepalive?: string;
}
interface NodeEditorProps {
node: NodeData;
onUpdate: (data: NodeData) => void;
onClose: () => void;
}
export default function NodeEditor({
node,
onUpdate,
onClose
}: NodeEditorProps): ReactNode {
const [formData, setFormData] = useState<NodeData>(node);
const [errors, setErrors] = useState<string[]>([]);
const handleInputChange = (field: keyof NodeData, value: string): void => {
setFormData(prev => ({
...prev,
[field]: value
}));
};
const handleSave = (): void => {
const validation = validateNodeConfig(formData);
if (!validation.isValid) {
setErrors(validation.errors);
return;
}
setErrors([]);
onUpdate(formData);
onClose();
};
return (
<div className="node-editor-overlay">
<div className="node-editor">
<div className="editor-header">
<h2>: {formData.label || '新节点'}</h2>
<button className="close-btn" onClick={onClose}>×</button>
</div>
{errors.length > 0 && (
<div className="error-box">
{errors.map((error, idx) => (
<p key={idx} className="error-message"> {error}</p>
))}
</div>
)}
<div className="form-group">
<label></label>
<input
type="text"
value={formData.label || ''}
onChange={(e) => handleInputChange('label', e.target.value)}
placeholder="例如: Node-A"
/>
</div>
<div className="form-group">
<label>IP地址</label>
<input
type="text"
value={formData.ipAddress || ''}
onChange={(e) => handleInputChange('ipAddress', e.target.value)}
placeholder="例如: 10.0.0.1"
/>
</div>
<div className="form-group">
<label></label>
<input
type="number"
value={formData.listenPort || ''}
onChange={(e) => handleInputChange('listenPort', e.target.value)}
placeholder="例如: 51820"
/>
</div>
<div className="form-group">
<label></label>
<textarea
value={formData.privateKey || ''}
onChange={(e) => handleInputChange('privateKey', e.target.value)}
placeholder="粘贴Base64编码的私钥"
rows={3}
/>
</div>
<div className="form-group">
<label></label>
<textarea
value={formData.publicKey || ''}
onChange={(e) => handleInputChange('publicKey', e.target.value)}
placeholder="粘贴Base64编码的公钥"
rows={3}
/>
</div>
<div className="form-group">
<label> ()</label>
<input
type="text"
value={formData.endpoint || ''}
onChange={(e) => handleInputChange('endpoint', e.target.value)}
placeholder="例如: 192.168.1.100:51820"
/>
</div>
<div className="form-group">
<label>DNS服务器 ()</label>
<input
type="text"
value={formData.dnsServers || ''}
onChange={(e) => handleInputChange('dnsServers', e.target.value)}
placeholder="例如: 8.8.8.8"
/>
</div>
<div className="form-group">
<label> ()</label>
<input
type="number"
value={formData.persistentKeepalive || ''}
onChange={(e) => handleInputChange('persistentKeepalive', e.target.value)}
placeholder="秒数"
/>
</div>
<div className="editor-actions">
<button className="btn-save" onClick={handleSave}></button>
<button className="btn-cancel" onClick={onClose}></button>
</div>
</div>
</div>
);
}