161 lines
5.2 KiB
TypeScript
161 lines
5.2 KiB
TypeScript
import { useState } from 'react';
|
|
import { useNavigate, useSearchParams } from 'react-router-dom';
|
|
import { useQuery, useMutation } from '@tanstack/react-query';
|
|
import { AdminLayout } from '@/components/layout/AdminLayout';
|
|
import { CommonNameForm } from '@/components/admin/CommonNameForm';
|
|
import { commonNamesApi, speciesApi, CommonName, Species } from '@/services/adminApi';
|
|
import { useToast } from '@/hooks/use-toast';
|
|
import { Button } from '@/components/ui/button';
|
|
import { ChevronLeft } from 'lucide-react';
|
|
import {
|
|
Select,
|
|
SelectContent,
|
|
SelectItem,
|
|
SelectTrigger,
|
|
SelectValue,
|
|
} from '@/components/ui/select';
|
|
import { Label } from '@/components/ui/label';
|
|
|
|
export default function CreateCommonName() {
|
|
const [isSubmitting, setIsSubmitting] = useState(false);
|
|
const [searchParams] = useSearchParams();
|
|
const { toast } = useToast();
|
|
const [selectedSpeciesId, setSelectedSpeciesId] = useState<string | null>(
|
|
searchParams.get('species_id')
|
|
);
|
|
const navigate = useNavigate();
|
|
|
|
// Fetch all species for the dropdown
|
|
const { data: species, isLoading: speciesLoading } = useQuery({
|
|
queryKey: ['admin', 'species', 'all'],
|
|
queryFn: async () => {
|
|
const { data } = await speciesApi.getAll(1, 500); // Fetch up to 500 species
|
|
return data;
|
|
}
|
|
});
|
|
|
|
// If a species_id was provided in the URL params, fetch that species details
|
|
const { data: selectedSpecies } = useQuery({
|
|
queryKey: ['admin', 'species', selectedSpeciesId],
|
|
queryFn: () => selectedSpeciesId ? speciesApi.getById(selectedSpeciesId) : null,
|
|
enabled: !!selectedSpeciesId
|
|
});
|
|
|
|
// Create common name mutation
|
|
const createMutation = useMutation({
|
|
mutationFn: (data: CommonName) => commonNamesApi.create(data),
|
|
onSuccess: () => {
|
|
toast({
|
|
title: 'Success',
|
|
description: 'Common name has been added successfully.',
|
|
});
|
|
|
|
// Navigate back to species detail page if we came from there
|
|
// if (selectedSpeciesId) {
|
|
// navigate(`/admin/species/${selectedSpeciesId}`);
|
|
// } else {
|
|
// navigate('/admin/common-names');
|
|
// }
|
|
},
|
|
onError: (error) => {
|
|
toast({
|
|
variant: 'destructive',
|
|
title: 'Error',
|
|
description: `Failed to create common name: ${(error as Error).message}`,
|
|
});
|
|
// setIsSubmitting(false); // Will be handled by onSettled
|
|
},
|
|
onSettled: () => {
|
|
setIsSubmitting(false);
|
|
}
|
|
});
|
|
|
|
const handleSubmit = (data: CommonName) => {
|
|
setIsSubmitting(true);
|
|
createMutation.mutate(data);
|
|
};
|
|
|
|
const handleSpeciesChange = (value: string) => {
|
|
setSelectedSpeciesId(value);
|
|
};
|
|
|
|
return (
|
|
<AdminLayout>
|
|
<div className="mb-6">
|
|
<Button
|
|
variant="outline"
|
|
className="mb-4"
|
|
onClick={() => navigate('/admin/common-names')}
|
|
>
|
|
<ChevronLeft className="mr-2 h-4 w-4" />
|
|
Back to Common Names
|
|
</Button>
|
|
|
|
<h1 className="text-3xl font-bold">Add New Common Name</h1>
|
|
<p className="text-muted-foreground">Create a new common name for a species</p>
|
|
</div>
|
|
|
|
{/* Species selection dropdown (only if not pre-selected) */}
|
|
{!searchParams.get('species_id') && (
|
|
<div className="mb-6 rounded-md border p-6">
|
|
<Label htmlFor="species-select" className="text-lg font-medium">
|
|
Select Species
|
|
</Label>
|
|
<p className="mb-4 text-sm text-muted-foreground">
|
|
Choose the species for this common name
|
|
</p>
|
|
|
|
<div className="max-w-md">
|
|
<Select
|
|
value={selectedSpeciesId || ''}
|
|
onValueChange={handleSpeciesChange}
|
|
disabled={speciesLoading}
|
|
>
|
|
<SelectTrigger className="w-full">
|
|
<SelectValue placeholder="Select a species" />
|
|
</SelectTrigger>
|
|
<SelectContent>
|
|
{species?.map((s: Species) => (
|
|
<SelectItem key={s.id} value={s.id!}>
|
|
<span className="italic">{s.scientific_name}</span>
|
|
{' - '}
|
|
<span>{s.common_name}</span>
|
|
</SelectItem>
|
|
))}
|
|
</SelectContent>
|
|
</Select>
|
|
</div>
|
|
</div>
|
|
)}
|
|
|
|
{/* Only show the form if a species is selected */}
|
|
{selectedSpeciesId ? (
|
|
<div className="rounded-md border p-6">
|
|
<div className="mb-4">
|
|
<h2 className="text-xl font-semibold">
|
|
{selectedSpecies ? (
|
|
<>
|
|
New Common Name for <span className="italic">{selectedSpecies.scientific_name}</span>
|
|
</>
|
|
) : (
|
|
'New Common Name'
|
|
)}
|
|
</h2>
|
|
</div>
|
|
|
|
<CommonNameForm
|
|
onSubmit={handleSubmit}
|
|
isSubmitting={isSubmitting}
|
|
speciesId={selectedSpeciesId}
|
|
/>
|
|
</div>
|
|
) : (
|
|
!searchParams.get('species_id') && (
|
|
<div className="rounded-md border p-6 text-center">
|
|
<p className="text-muted-foreground">Please select a species to continue</p>
|
|
</div>
|
|
)
|
|
)}
|
|
</AdminLayout>
|
|
);
|
|
} |