geocrop-platform./apps/web/src/JobForm.tsx

96 lines
3.7 KiB
TypeScript

import React, { useState, useEffect } from 'react';
import axios from 'axios';
interface JobFormProps {
onJobSubmitted: (jobId: string) => void;
selectedLat?: string;
selectedLon?: string;
}
const API_ENDPOINT = 'https://api.portfolio.techarvest.co.zw';
const JobForm: React.FC<JobFormProps> = ({ onJobSubmitted, selectedLat, selectedLon }) => {
const [lat, setLat] = useState<string>('-17.8');
const [lon, setLon] = useState<string>('31.0');
const [radius, setRadius] = useState<number>(2000);
const [year, setYear] = useState<string>('2022');
const [loading, setLoading] = useState(false);
useEffect(() => {
if (selectedLat) setLat(selectedLat);
if (selectedLon) setLon(selectedLon);
}, [selectedLat, selectedLon]);
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
const token = localStorage.getItem('token');
if (!token) {
alert('Authentication required.');
return;
}
setLoading(true);
try {
const response = await axios.post(`${API_ENDPOINT}/jobs`, {
lat: parseFloat(lat),
lon: parseFloat(lon),
radius_km: radius / 1000,
year: year,
model_name: 'Ensemble'
}, {
headers: {
'Authorization': `Bearer ${token}`
}
});
onJobSubmitted(response.data.job_id);
} catch (err) {
console.error('Failed to submit job:', err);
alert('Failed to submit job. Check console.');
} finally {
setLoading(false);
}
};
return (
<form onSubmit={handleSubmit} style={{ display: 'flex', flexDirection: 'column', gap: '10px', marginTop: '15px', borderTop: '1px solid #eee', paddingTop: '15px' }}>
<h2 style={{ fontSize: '16px', margin: 0, fontWeight: 'bold' }}>Submit New Job</h2>
<div style={{ display: 'flex', gap: '10px' }}>
<div style={{ flex: 1 }}>
<label style={{ fontSize: '11px', color: '#666' }}>Lat</label>
<input type="text" placeholder="Lat" value={lat} onChange={(e) => setLat(e.target.value)} style={{ width: '100%', padding: '8px', border: '1px solid #ddd', borderRadius: '4px', boxSizing: 'border-box' }} />
</div>
<div style={{ flex: 1 }}>
<label style={{ fontSize: '11px', color: '#666' }}>Lon</label>
<input type="text" placeholder="Lon" value={lon} onChange={(e) => setLon(e.target.value)} style={{ width: '100%', padding: '8px', border: '1px solid #ddd', borderRadius: '4px', boxSizing: 'border-box' }} />
</div>
</div>
<div>
<label style={{ fontSize: '11px', color: '#666' }}>Radius (meters)</label>
<input type="number" placeholder="Radius (m)" value={radius} onChange={(e) => setRadius(parseInt(e.target.value))} style={{ width: '100%', padding: '8px', border: '1px solid #ddd', borderRadius: '4px', boxSizing: 'border-box' }} />
</div>
<div>
<label style={{ fontSize: '11px', color: '#666' }}>Season Year</label>
<select value={year} onChange={(e) => setYear(e.target.value)} style={{ width: '100%', padding: '8px', border: '1px solid #ddd', borderRadius: '4px', boxSizing: 'border-box' }}>
{[2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024, 2025].map(y => (
<option key={y} value={y.toString()}>{y}</option>
))}
</select>
</div>
<button type="submit" disabled={loading} style={{
background: '#28a745',
color: 'white',
border: 'none',
padding: '12px',
borderRadius: '4px',
cursor: loading ? 'not-allowed' : 'pointer',
fontWeight: 'bold',
marginTop: '5px'
}}>
{loading ? 'Submitting...' : 'Run Classification'}
</button>
</form>
);
};
export default JobForm;