Files
experiments-database/frontend/src/components/ExperimentForm.jsx
T

75 lines
2.2 KiB
React
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 React, { useState, useEffect } from 'react';
import Button from './ui/Button';
import FormField, { Input } from './ui/FormField';
import Alert from './ui/Alert';
import { experimentsApi } from '../api/client';
export default function ExperimentForm({ existing, onSuccess, onCancel }) {
const [title, setTitle] = useState(existing?.title ?? '');
const [errors, setErrors] = useState({});
const [apiError, setApiError] = useState(null);
const [loading, setLoading] = useState(false);
useEffect(() => {
setTitle(existing?.title ?? '');
setErrors({});
setApiError(null);
}, [existing]);
function validate() {
const e = {};
if (!title.trim()) e.title = 'Title is required';
else if (title.trim().length > 255) e.title = 'Title must be 255 characters or fewer';
setErrors(e);
return Object.keys(e).length === 0;
}
async function handleSubmit(e) {
e.preventDefault();
if (!validate()) return;
setLoading(true);
setApiError(null);
try {
const result = existing
? await experimentsApi.update(existing.id, { title: title.trim() })
: await experimentsApi.create({ title: title.trim() });
onSuccess(result);
} catch (err) {
setApiError(err);
} finally {
setLoading(false);
}
}
return (
<form onSubmit={handleSubmit} noValidate className="space-y-4">
{apiError && (
<Alert
type="error"
message={apiError.message}
details={apiError.details}
onDismiss={() => setApiError(null)}
/>
)}
<FormField label="Experiment Title" name="title" error={errors.title} required>
<Input
name="title"
value={title}
onChange={(e) => setTitle(e.target.value)}
placeholder="e.g. Drug Efficacy Study Q3"
required
disabled={loading}
/>
</FormField>
<div className="flex justify-end gap-3 pt-2">
<Button variant="secondary" type="button" onClick={onCancel} disabled={loading}>
Cancel
</Button>
<Button type="submit" loading={loading}>
{existing ? 'Save Changes' : 'Create Experiment'}
</Button>
</div>
</form>
);
}