Files
energy-trade/frontend/src/components/forms/SettingsForm.tsx
kbt-devops c6bca0b7bb Add React frontend for energy trading system
Implements React + TypeScript UI with Vite and Tailwind CSS.
Features dashboard with real-time WebSocket updates, backtesting
page, model management interface, trading controls, and settings.
Includes state management with Zustand, API integration with
Axios/TanStack Query, and interactive charts with Recharts.
2026-02-12 01:01:08 +07:00

92 lines
3.6 KiB
TypeScript

import { useState, useEffect } from 'react';
import type { AppSettings } from '@/services/types';
interface SettingsFormProps {
onSubmit: (settings: Partial<AppSettings>) => void;
isLoading?: boolean;
}
export default function SettingsForm({ onSubmit, isLoading }: SettingsFormProps) {
const [settings, setSettings] = useState<AppSettings>({
battery_min_reserve: 0.1,
battery_max_charge: 0.9,
arbitrage_min_spread: 5.0,
mining_margin_threshold: 5.0,
});
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
onSubmit(settings);
};
return (
<form onSubmit={handleSubmit} className="space-y-6">
<div className="bg-gray-800 p-4 rounded-lg">
<h3 className="text-lg font-semibold text-white mb-4">Battery Settings</h3>
<div className="grid grid-cols-2 gap-4">
<div>
<label className="block text-sm font-medium text-gray-300 mb-2">Minimum Reserve</label>
<input
type="number"
step="0.01"
min="0"
max="1"
value={settings.battery_min_reserve}
onChange={(e) => setSettings({ ...settings, battery_min_reserve: parseFloat(e.target.value) })}
className="w-full px-4 py-2 bg-gray-700 border border-gray-600 rounded-lg text-white focus:outline-none focus:border-primary-500"
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-300 mb-2">Maximum Charge</label>
<input
type="number"
step="0.01"
min="0"
max="1"
value={settings.battery_max_charge}
onChange={(e) => setSettings({ ...settings, battery_max_charge: parseFloat(e.target.value) })}
className="w-full px-4 py-2 bg-gray-700 border border-gray-600 rounded-lg text-white focus:outline-none focus:border-primary-500"
/>
</div>
</div>
</div>
<div className="bg-gray-800 p-4 rounded-lg">
<h3 className="text-lg font-semibold text-white mb-4">Trading Settings</h3>
<div className="grid grid-cols-2 gap-4">
<div>
<label className="block text-sm font-medium text-gray-300 mb-2">Min Arbitrage Spread (/MWh)</label>
<input
type="number"
step="0.1"
min="0"
value={settings.arbitrage_min_spread}
onChange={(e) => setSettings({ ...settings, arbitrage_min_spread: parseFloat(e.target.value) })}
className="w-full px-4 py-2 bg-gray-700 border border-gray-600 rounded-lg text-white focus:outline-none focus:border-primary-500"
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-300 mb-2">Mining Margin Threshold (/MWh)</label>
<input
type="number"
step="0.1"
min="0"
value={settings.mining_margin_threshold}
onChange={(e) => setSettings({ ...settings, mining_margin_threshold: parseFloat(e.target.value) })}
className="w-full px-4 py-2 bg-gray-700 border border-gray-600 rounded-lg text-white focus:outline-none focus:border-primary-500"
/>
</div>
</div>
</div>
<button
type="submit"
disabled={isLoading}
className="w-full px-4 py-3 bg-primary-600 hover:bg-primary-700 disabled:bg-gray-700 disabled:text-gray-500 text-white rounded-lg font-medium transition-colors"
>
{isLoading ? 'Saving...' : 'Save Settings'}
</button>
</form>
);
}