Fix bucket edit + delete buttons

This commit is contained in:
myrmidex 2025-12-30 20:50:13 +01:00
parent 2e633d75da
commit fdf6fb02d7

View file

@ -30,19 +30,59 @@ interface Props {
export default function Show({ scenario, buckets }: Props) { export default function Show({ scenario, buckets }: Props) {
const [isModalOpen, setIsModalOpen] = useState(false); const [isModalOpen, setIsModalOpen] = useState(false);
const [isSubmitting, setIsSubmitting] = useState(false); const [isSubmitting, setIsSubmitting] = useState(false);
const [editingBucket, setEditingBucket] = useState<Bucket | null>(null);
const [formData, setFormData] = useState({ const [formData, setFormData] = useState({
name: '', name: '',
allocation_type: 'fixed_limit', allocation_type: 'fixed_limit',
allocation_value: '' allocation_value: ''
}); });
const handleEdit = (bucket: Bucket) => {
setEditingBucket(bucket);
setFormData({
name: bucket.name,
allocation_type: bucket.allocation_type,
allocation_value: bucket.allocation_value ? bucket.allocation_value.toString() : ''
});
setIsModalOpen(true);
};
const handleDelete = async (bucket: Bucket) => {
if (!confirm(`Are you sure you want to delete "${bucket.name}"?`)) {
return;
}
try {
const response = await fetch(`/buckets/${bucket.id}`, {
method: 'DELETE',
headers: {
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]')?.getAttribute('content') || '',
},
});
if (response.ok) {
router.reload({ only: ['buckets'] });
} else {
console.error('Failed to delete bucket');
}
} catch (error) {
console.error('Error deleting bucket:', error);
}
};
const handleSubmit = async (e: React.FormEvent) => { const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault(); e.preventDefault();
setIsSubmitting(true); setIsSubmitting(true);
const url = editingBucket
? `/buckets/${editingBucket.id}`
: `/scenarios/${scenario.id}/buckets`;
const method = editingBucket ? 'PATCH' : 'POST';
try { try {
const response = await fetch(`/scenarios/${scenario.id}/buckets`, { const response = await fetch(url, {
method: 'POST', method: method,
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]')?.getAttribute('content') || '', 'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]')?.getAttribute('content') || '',
@ -50,20 +90,22 @@ export default function Show({ scenario, buckets }: Props) {
body: JSON.stringify({ body: JSON.stringify({
name: formData.name, name: formData.name,
allocation_type: formData.allocation_type, allocation_type: formData.allocation_type,
allocation_value: formData.allocation_value ? parseFloat(formData.allocation_value) : null allocation_value: formData.allocation_value ? parseFloat(formData.allocation_value) : null,
priority: editingBucket ? editingBucket.priority : undefined
}), }),
}); });
if (response.ok) { if (response.ok) {
setIsModalOpen(false); setIsModalOpen(false);
setFormData({ name: '', allocation_type: 'fixed_limit', allocation_value: '' }); setFormData({ name: '', allocation_type: 'fixed_limit', allocation_value: '' });
setEditingBucket(null);
router.reload({ only: ['buckets'] }); router.reload({ only: ['buckets'] });
} else { } else {
const errorData = await response.json(); const errorData = await response.json();
console.error('Failed to create bucket:', errorData); console.error(`Failed to ${editingBucket ? 'update' : 'create'} bucket:`, errorData);
} }
} catch (error) { } catch (error) {
console.error('Error creating bucket:', error); console.error(`Error ${editingBucket ? 'updating' : 'creating'} bucket:`, error);
} finally { } finally {
setIsSubmitting(false); setIsSubmitting(false);
} }
@ -135,7 +177,11 @@ export default function Show({ scenario, buckets }: Props) {
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<h2 className="text-xl font-semibold text-gray-900">Buckets</h2> <h2 className="text-xl font-semibold text-gray-900">Buckets</h2>
<button <button
onClick={() => setIsModalOpen(true)} onClick={() => {
setEditingBucket(null);
setFormData({ name: '', allocation_type: 'fixed_limit', allocation_value: '' });
setIsModalOpen(true);
}}
className="rounded-md bg-blue-600 px-4 py-2 text-sm font-semibold text-white hover:bg-blue-500" className="rounded-md bg-blue-600 px-4 py-2 text-sm font-semibold text-white hover:bg-blue-500"
> >
+ Add Bucket + Add Bucket
@ -219,10 +265,16 @@ export default function Show({ scenario, buckets }: Props) {
</div> </div>
<div className="mt-4 flex gap-2"> <div className="mt-4 flex gap-2">
<button className="flex-1 text-sm text-blue-600 hover:text-blue-500"> <button
onClick={() => handleEdit(bucket)}
className="flex-1 text-sm text-blue-600 hover:text-blue-500"
>
Edit Edit
</button> </button>
<button className="flex-1 text-sm text-red-600 hover:text-red-500"> <button
onClick={() => handleDelete(bucket)}
className="flex-1 text-sm text-red-600 hover:text-red-500"
>
Delete Delete
</button> </button>
</div> </div>
@ -268,7 +320,7 @@ export default function Show({ scenario, buckets }: Props) {
<div className="fixed inset-0 bg-gray-600 bg-opacity-50 overflow-y-auto h-full w-full z-50"> <div className="fixed inset-0 bg-gray-600 bg-opacity-50 overflow-y-auto h-full w-full z-50">
<div className="relative top-20 mx-auto p-5 border w-96 shadow-lg rounded-md bg-white"> <div className="relative top-20 mx-auto p-5 border w-96 shadow-lg rounded-md bg-white">
<div className="mt-3"> <div className="mt-3">
<h3 className="text-lg font-medium text-gray-900 mb-4">Add New Bucket</h3> <h3 className="text-lg font-medium text-gray-900 mb-4">{editingBucket ? 'Edit Bucket' : 'Add New Bucket'}</h3>
<form onSubmit={handleSubmit} className="space-y-4"> <form onSubmit={handleSubmit} className="space-y-4">
<div> <div>
<label htmlFor="name" className="block text-sm font-medium text-gray-700"> <label htmlFor="name" className="block text-sm font-medium text-gray-700">
@ -324,7 +376,11 @@ export default function Show({ scenario, buckets }: Props) {
<div className="flex gap-3 pt-4"> <div className="flex gap-3 pt-4">
<button <button
type="button" type="button"
onClick={() => setIsModalOpen(false)} onClick={() => {
setIsModalOpen(false);
setEditingBucket(null);
setFormData({ name: '', allocation_type: 'fixed_limit', allocation_value: '' });
}}
className="flex-1 px-4 py-2 text-sm font-medium text-gray-700 bg-gray-200 rounded-md hover:bg-gray-300" className="flex-1 px-4 py-2 text-sm font-medium text-gray-700 bg-gray-200 rounded-md hover:bg-gray-300"
disabled={isSubmitting} disabled={isSubmitting}
> >
@ -335,7 +391,7 @@ export default function Show({ scenario, buckets }: Props) {
className="flex-1 px-4 py-2 text-sm font-medium text-white bg-blue-600 rounded-md hover:bg-blue-700 disabled:opacity-50" className="flex-1 px-4 py-2 text-sm font-medium text-white bg-blue-600 rounded-md hover:bg-blue-700 disabled:opacity-50"
disabled={isSubmitting} disabled={isSubmitting}
> >
{isSubmitting ? 'Creating...' : 'Create Bucket'} {isSubmitting ? (editingBucket ? 'Updating...' : 'Creating...') : (editingBucket ? 'Update Bucket' : 'Create Bucket')}
</button> </button>
</div> </div>
</form> </form>