778 lines
23 KiB
TypeScript
778 lines
23 KiB
TypeScript
import { supabase } from './supabase';
|
|
import { Database } from '../types/supabase';
|
|
import { v4 as uuidv4 } from 'uuid';
|
|
|
|
export type Species = Database['public']['Tables']['species']['Row'] & {
|
|
common_names?: CommonName[];
|
|
primary_common_name?: string;
|
|
};
|
|
export type CommonName = Database['public']['Tables']['common_names']['Row'];
|
|
export type Subpopulation = Database['public']['Tables']['subpopulations']['Row'];
|
|
export type IucnAssessment = Database['public']['Tables']['iucn_assessments']['Row'];
|
|
|
|
// Update the type definition to match the actual database structure
|
|
export type CitesListing = Omit<Database['public']['Tables']['cites_listings']['Row'], 'listing_date'> & {
|
|
listing_date: string;
|
|
};
|
|
|
|
export type CitesTradeRecord = Database['public']['Tables']['cites_trade_records']['Row'];
|
|
export type TimelineEvent = Database['public']['Tables']['timeline_events']['Row'];
|
|
|
|
export type SpeciesDetails = Species & {
|
|
common_names: CommonName[];
|
|
subpopulations: Subpopulation[];
|
|
iucn_assessments: IucnAssessment[];
|
|
cites_listings: CitesListing[];
|
|
latest_assessment?: IucnAssessment;
|
|
current_cites_listing?: CitesListing;
|
|
};
|
|
|
|
export async function getAllSpecies() {
|
|
try {
|
|
console.log("Fetching all species from database...");
|
|
// First get all species
|
|
const { data: allSpecies, error: speciesError } = await supabase
|
|
.from('species')
|
|
.select('*')
|
|
.order('scientific_name');
|
|
|
|
if (speciesError) {
|
|
console.error("Error fetching species:", speciesError);
|
|
throw speciesError;
|
|
}
|
|
|
|
if (!allSpecies || allSpecies.length === 0) {
|
|
console.warn("No species found in database!");
|
|
return [];
|
|
}
|
|
|
|
console.log(`Fetched ${allSpecies.length} total species records`);
|
|
|
|
// Manually filter out duplicates by scientific_name
|
|
const uniqueSpeciesMap = new Map();
|
|
allSpecies.forEach(species => {
|
|
if (!uniqueSpeciesMap.has(species.scientific_name)) {
|
|
uniqueSpeciesMap.set(species.scientific_name, species);
|
|
}
|
|
});
|
|
|
|
const distinctSpecies = Array.from(uniqueSpeciesMap.values());
|
|
console.log(`Filtered to ${distinctSpecies.length} distinct species`);
|
|
|
|
// Then get common names for all species
|
|
const { data: commonNames, error: commonNamesError } = await supabase
|
|
.from('common_names')
|
|
.select('*')
|
|
.in('species_id', distinctSpecies.map(s => s.id));
|
|
|
|
if (commonNamesError) {
|
|
console.error("Error fetching common names:", commonNamesError);
|
|
throw commonNamesError;
|
|
}
|
|
|
|
console.log(`Fetched ${commonNames?.length || 0} common names`);
|
|
|
|
// Group common names by species_id
|
|
const commonNamesBySpecies = new Map();
|
|
commonNames?.forEach(cn => {
|
|
if (!commonNamesBySpecies.has(cn.species_id)) {
|
|
commonNamesBySpecies.set(cn.species_id, []);
|
|
}
|
|
commonNamesBySpecies.get(cn.species_id).push(cn);
|
|
});
|
|
|
|
// Transform the data to include primary_common_name
|
|
const transformedSpecies = distinctSpecies.map(species => ({
|
|
...species,
|
|
common_names: commonNamesBySpecies.get(species.id) || [],
|
|
primary_common_name: commonNamesBySpecies.get(species.id)?.[0]?.name || species.common_name || species.scientific_name
|
|
}));
|
|
|
|
return transformedSpecies;
|
|
} catch (error) {
|
|
console.error("Error in getAllSpecies:", error);
|
|
return []; // Return empty array instead of throwing to avoid breaking the UI
|
|
}
|
|
}
|
|
|
|
export async function getSpeciesById(id: string): Promise<SpeciesDetails | null> {
|
|
try {
|
|
// Get species basic info
|
|
const { data: species, error: speciesError } = await supabase
|
|
.from('species')
|
|
.select('*')
|
|
.eq('id', id)
|
|
.single();
|
|
|
|
if (speciesError) throw speciesError;
|
|
if (!species) return null;
|
|
|
|
// Get common names
|
|
const { data: commonNames, error: commonNamesError } = await supabase
|
|
.from('common_names')
|
|
.select('*')
|
|
.eq('species_id', id);
|
|
|
|
if (commonNamesError) throw commonNamesError;
|
|
|
|
// Get subpopulations
|
|
const { data: subpopulations, error: subpopulationsError } = await supabase
|
|
.from('subpopulations')
|
|
.select('*')
|
|
.eq('species_id', id);
|
|
|
|
if (subpopulationsError) throw subpopulationsError;
|
|
|
|
// Get IUCN assessments
|
|
const { data: iucnAssessments, error: iucnError } = await supabase
|
|
.from('iucn_assessments')
|
|
.select('*')
|
|
.eq('species_id', id)
|
|
.order('year_published', { ascending: false });
|
|
|
|
if (iucnError) throw iucnError;
|
|
|
|
// Approach 1: Just get all CITES listings without any filtering
|
|
console.log('Getting all CITES listings');
|
|
const { data: allListings, error: allListingsError } = await supabase
|
|
.from('cites_listings')
|
|
.select('*');
|
|
|
|
if (allListingsError) {
|
|
console.error('Error getting ALL listings:', allListingsError);
|
|
throw allListingsError;
|
|
}
|
|
|
|
console.log('All listings in database:', allListings);
|
|
|
|
// Now manually filter to this species
|
|
const citesListings = allListings.filter(listing =>
|
|
listing.species_id === id
|
|
);
|
|
|
|
console.log(`Found ${citesListings.length} listings for species ID ${id}:`, citesListings);
|
|
|
|
// Find latest assessment
|
|
const latestAssessment = iucnAssessments?.find(a => a.is_latest) ||
|
|
(iucnAssessments && iucnAssessments.length > 0 ? iucnAssessments[0] : undefined);
|
|
|
|
// Set current CITES listing
|
|
const currentCitesListing = citesListings.find(l => l.is_current) ||
|
|
(citesListings.length > 0 ? citesListings[0] : undefined);
|
|
|
|
// Construct the response
|
|
return {
|
|
...species,
|
|
common_names: commonNames || [],
|
|
subpopulations: subpopulations || [],
|
|
iucn_assessments: iucnAssessments || [],
|
|
cites_listings: citesListings,
|
|
latest_assessment: latestAssessment,
|
|
current_cites_listing: currentCitesListing,
|
|
};
|
|
} catch (error) {
|
|
console.error('Error in getSpeciesById:', error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
export async function getTimelineEvents(speciesId: string) {
|
|
const { data, error } = await supabase
|
|
.from('timeline_events')
|
|
.select('*')
|
|
.eq('species_id', speciesId)
|
|
.not('event_type', 'eq', 'cites_trade')
|
|
.order('event_date', { ascending: false });
|
|
|
|
if (error) throw error;
|
|
return data as TimelineEvent[];
|
|
}
|
|
|
|
export async function getCitesTradeRecords(speciesId: string) {
|
|
try {
|
|
console.log('getCitesTradeRecords called with species ID:', speciesId);
|
|
|
|
// First get the species details to have the scientific name as fallback
|
|
const { data: speciesData, error: speciesError } = await supabase
|
|
.from('species')
|
|
.select('scientific_name, common_name, family, genus, species_name')
|
|
.eq('id', speciesId)
|
|
.single();
|
|
|
|
if (speciesError) {
|
|
console.error('Error fetching species info:', speciesError);
|
|
} else {
|
|
console.log('Found species for trade lookup:', speciesData);
|
|
}
|
|
|
|
console.log('Fetching all CITES trade records...');
|
|
|
|
// Initialize array to store all records
|
|
let allRecords: CitesTradeRecord[] = [];
|
|
let page = 0;
|
|
const pageSize = 1000;
|
|
let hasMore = true;
|
|
|
|
// Fetch records in batches until we have all of them
|
|
while (hasMore) {
|
|
const { data: records, error: directError } = await supabase
|
|
.from('cites_trade_records')
|
|
.select('*')
|
|
.eq('species_id', speciesId)
|
|
.order('year', { ascending: false })
|
|
.range(page * pageSize, (page + 1) * pageSize - 1);
|
|
|
|
if (directError) {
|
|
console.error('Error with direct species_id query:', directError);
|
|
break;
|
|
}
|
|
|
|
if (!records || records.length === 0) {
|
|
hasMore = false;
|
|
break;
|
|
}
|
|
|
|
allRecords = [...allRecords, ...records];
|
|
console.log(`Fetched batch ${page + 1}, total records so far: ${allRecords.length}`);
|
|
|
|
// If we got less than the page size, we've reached the end
|
|
if (records.length < pageSize) {
|
|
hasMore = false;
|
|
} else {
|
|
page++;
|
|
}
|
|
}
|
|
|
|
if (allRecords.length > 0) {
|
|
console.log(`Found total of ${allRecords.length} records with direct species_id query`);
|
|
console.log('First few records:', allRecords.slice(0, 3));
|
|
console.log('Year range:', Math.min(...allRecords.map(r => r.year)),
|
|
'to', Math.max(...allRecords.map(r => r.year)));
|
|
return allRecords;
|
|
}
|
|
|
|
// If no direct matches found, try the fallback approach
|
|
console.log('No records found with direct query, trying fallback matching...');
|
|
|
|
// Reset pagination for fallback approach
|
|
allRecords = [];
|
|
page = 0;
|
|
hasMore = true;
|
|
|
|
while (hasMore) {
|
|
const { data: records, error: fallbackError } = await supabase
|
|
.from('cites_trade_records')
|
|
.select('*')
|
|
.order('year', { ascending: false })
|
|
.range(page * pageSize, (page + 1) * pageSize - 1);
|
|
|
|
if (fallbackError) {
|
|
console.error('Error with fallback query:', fallbackError);
|
|
break;
|
|
}
|
|
|
|
if (!records || records.length === 0) {
|
|
hasMore = false;
|
|
break;
|
|
}
|
|
|
|
// Filter records for this batch
|
|
const filteredRecords = records.filter(record => {
|
|
// Try scientific name match with the taxon field
|
|
if (record.taxon &&
|
|
speciesData?.scientific_name &&
|
|
record.taxon.toLowerCase() === speciesData.scientific_name.toLowerCase()) {
|
|
return true;
|
|
}
|
|
|
|
// Try family match
|
|
if (record.family &&
|
|
speciesData?.family &&
|
|
record.family.toLowerCase() === speciesData.family.toLowerCase()) {
|
|
|
|
// For family matches, also check genus if available
|
|
if (record.genus &&
|
|
speciesData.genus &&
|
|
record.genus.toLowerCase() === speciesData.genus.toLowerCase()) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
});
|
|
|
|
allRecords = [...allRecords, ...filteredRecords];
|
|
console.log(`Fetched batch ${page + 1}, total filtered records so far: ${allRecords.length}`);
|
|
|
|
if (records.length < pageSize) {
|
|
hasMore = false;
|
|
} else {
|
|
page++;
|
|
}
|
|
}
|
|
|
|
if (allRecords.length > 0) {
|
|
console.log(`Found total of ${allRecords.length} trade records after filtering`);
|
|
console.log('Year range:', Math.min(...allRecords.map(r => r.year)),
|
|
'to', Math.max(...allRecords.map(r => r.year)));
|
|
}
|
|
|
|
// Sort by year descending
|
|
allRecords.sort((a, b) => b.year - a.year);
|
|
|
|
return allRecords;
|
|
} catch (error) {
|
|
console.error('Error in getCitesTradeRecords:', error);
|
|
return [];
|
|
}
|
|
}
|
|
|
|
// Function to search species by scientific or common name
|
|
export async function searchSpecies(query: string) {
|
|
if (!query || query.length < 3) return [];
|
|
|
|
// First search in scientific_name and common_name fields
|
|
const { data: speciesResults, error: speciesError } = await supabase
|
|
.from('species')
|
|
.select('*')
|
|
.or(`scientific_name.ilike.%${query}%,common_name.ilike.%${query}%`)
|
|
.limit(20);
|
|
|
|
if (speciesError) throw speciesError;
|
|
|
|
// Also search in common_names table
|
|
const { data: commonNamesResults, error: commonNamesError } = await supabase
|
|
.from('common_names')
|
|
.select('*, species!inner(*)')
|
|
.ilike('name', `%${query}%`)
|
|
.limit(20);
|
|
|
|
if (commonNamesError) throw commonNamesError;
|
|
|
|
// Combine the results, removing duplicates
|
|
const speciesMap = new Map<string, Species>();
|
|
|
|
if (speciesResults) {
|
|
for (const species of speciesResults) {
|
|
speciesMap.set(species.id, species);
|
|
}
|
|
}
|
|
|
|
if (commonNamesResults) {
|
|
for (const result of commonNamesResults) {
|
|
if (result.species) {
|
|
speciesMap.set(result.species.id, result.species);
|
|
}
|
|
}
|
|
}
|
|
|
|
return Array.from(speciesMap.values());
|
|
}
|
|
|
|
export async function updateSpeciesImage(speciesId: string, imageUrl: string) {
|
|
const { error } = await supabase
|
|
.from('species')
|
|
.update({ default_image_url: imageUrl })
|
|
.eq('id', speciesId);
|
|
|
|
if (error) {
|
|
console.error('Error updating species image:', error);
|
|
}
|
|
}
|
|
|
|
export async function getSpeciesImages(scientificName: string) {
|
|
try {
|
|
console.log('Fetching images for species:', scientificName);
|
|
|
|
// First try to get from iNaturalist API
|
|
const response = await fetch(
|
|
`https://api.inaturalist.org/v1/taxa?q=${encodeURIComponent(scientificName)}&order=desc&order_by=observations_count`
|
|
);
|
|
const data = await response.json();
|
|
|
|
if (data.results && data.results[0] && data.results[0].default_photo) {
|
|
console.log('Found image from iNaturalist:', data.results[0].default_photo);
|
|
return {
|
|
url: data.results[0].default_photo.medium_url,
|
|
attribution: data.results[0].default_photo.attribution,
|
|
license: data.results[0].default_photo.license_code
|
|
};
|
|
}
|
|
|
|
console.log('No image found for species:', scientificName);
|
|
return null;
|
|
} catch (error) {
|
|
console.error('Error fetching species images:', error);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
// CRUD functions for CITES listings
|
|
|
|
export async function createCitesListing(listing: Omit<Database['public']['Tables']['cites_listings']['Insert'], 'id'>) {
|
|
try {
|
|
const newListing = {
|
|
...listing,
|
|
id: uuidv4()
|
|
};
|
|
|
|
console.log('Creating new CITES listing:', newListing);
|
|
|
|
const { data, error } = await supabase
|
|
.from('cites_listings')
|
|
.insert(newListing)
|
|
.select()
|
|
.single();
|
|
|
|
if (error) {
|
|
console.error('Error creating CITES listing:', error);
|
|
throw error;
|
|
}
|
|
|
|
// If this is set as current, update other listings to not be current
|
|
if (newListing.is_current) {
|
|
await updateCitesListingsCurrent(newListing.species_id, newListing.id);
|
|
}
|
|
|
|
return data;
|
|
} catch (error) {
|
|
console.error('Error in createCitesListing:', error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
export async function updateCitesListing(id: string, updates: Database['public']['Tables']['cites_listings']['Update']) {
|
|
try {
|
|
console.log(`Updating CITES listing ${id}:`, updates);
|
|
|
|
// First get the current listing to check if we need to update current status
|
|
const { data: currentListing, error: fetchError } = await supabase
|
|
.from('cites_listings')
|
|
.select('species_id')
|
|
.eq('id', id)
|
|
.single();
|
|
|
|
if (fetchError) {
|
|
console.error('Error fetching CITES listing for update:', fetchError);
|
|
throw fetchError;
|
|
}
|
|
|
|
// Update the listing
|
|
const { data, error } = await supabase
|
|
.from('cites_listings')
|
|
.update(updates)
|
|
.eq('id', id)
|
|
.select()
|
|
.single();
|
|
|
|
if (error) {
|
|
console.error('Error updating CITES listing:', error);
|
|
throw error;
|
|
}
|
|
|
|
// If this is set as current, update other listings to not be current
|
|
if (updates.is_current && currentListing) {
|
|
await updateCitesListingsCurrent(currentListing.species_id, id);
|
|
}
|
|
|
|
return data;
|
|
} catch (error) {
|
|
console.error('Error in updateCitesListing:', error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
export async function deleteCitesListing(id: string) {
|
|
try {
|
|
console.log(`Deleting CITES listing ${id}`);
|
|
|
|
// First get the current listing to check if we need to update current status
|
|
const { data: currentListing, error: fetchError } = await supabase
|
|
.from('cites_listings')
|
|
.select('species_id, is_current')
|
|
.eq('id', id)
|
|
.single();
|
|
|
|
if (fetchError) {
|
|
console.error('Error fetching CITES listing for deletion:', fetchError);
|
|
throw fetchError;
|
|
}
|
|
|
|
// Delete the listing
|
|
const { error } = await supabase
|
|
.from('cites_listings')
|
|
.delete()
|
|
.eq('id', id);
|
|
|
|
if (error) {
|
|
console.error('Error deleting CITES listing:', error);
|
|
throw error;
|
|
}
|
|
|
|
// If this was the current listing, set another one as current
|
|
if (currentListing && currentListing.is_current) {
|
|
const { data: remainingListings, error: listingsError } = await supabase
|
|
.from('cites_listings')
|
|
.select('id')
|
|
.eq('species_id', currentListing.species_id)
|
|
.order('listing_date', { ascending: false })
|
|
.limit(1);
|
|
|
|
if (listingsError) {
|
|
console.error('Error fetching remaining listings:', listingsError);
|
|
} else if (remainingListings && remainingListings.length > 0) {
|
|
await updateCitesListing(remainingListings[0].id, { is_current: true });
|
|
}
|
|
}
|
|
|
|
return true;
|
|
} catch (error) {
|
|
console.error('Error in deleteCitesListing:', error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
// Helper function to update current status of CITES listings
|
|
async function updateCitesListingsCurrent(speciesId: string, currentId: string) {
|
|
try {
|
|
console.log(`Setting listing ${currentId} as current for species ${speciesId}`);
|
|
|
|
const { error } = await supabase
|
|
.from('cites_listings')
|
|
.update({ is_current: false })
|
|
.eq('species_id', speciesId)
|
|
.neq('id', currentId);
|
|
|
|
if (error) {
|
|
console.error('Error updating CITES listings current status:', error);
|
|
throw error;
|
|
}
|
|
|
|
return true;
|
|
} catch (error) {
|
|
console.error('Error in updateCitesListingsCurrent:', error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
// CRUD functions for timeline events
|
|
|
|
export async function createTimelineEvent(event: Omit<Database['public']['Tables']['timeline_events']['Insert'], 'id'>) {
|
|
try {
|
|
const newEvent = {
|
|
...event,
|
|
id: uuidv4()
|
|
};
|
|
|
|
console.log('Creating new timeline event:', newEvent);
|
|
|
|
const { data, error } = await supabase
|
|
.from('timeline_events')
|
|
.insert(newEvent)
|
|
.select()
|
|
.single();
|
|
|
|
if (error) {
|
|
console.error('Error creating timeline event:', error);
|
|
throw error;
|
|
}
|
|
|
|
return data;
|
|
} catch (error) {
|
|
console.error('Error in createTimelineEvent:', error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
export async function updateTimelineEvent(id: string, updates: Database['public']['Tables']['timeline_events']['Update']) {
|
|
try {
|
|
console.log(`Updating timeline event ${id}:`, updates);
|
|
|
|
const { data, error } = await supabase
|
|
.from('timeline_events')
|
|
.update(updates)
|
|
.eq('id', id)
|
|
.select()
|
|
.single();
|
|
|
|
if (error) {
|
|
console.error('Error updating timeline event:', error);
|
|
throw error;
|
|
}
|
|
|
|
return data;
|
|
} catch (error) {
|
|
console.error('Error in updateTimelineEvent:', error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
export async function deleteTimelineEvent(id: string) {
|
|
try {
|
|
console.log(`Deleting timeline event ${id}`);
|
|
|
|
const { error } = await supabase
|
|
.from('timeline_events')
|
|
.delete()
|
|
.eq('id', id);
|
|
|
|
if (error) {
|
|
console.error('Error deleting timeline event:', error);
|
|
throw error;
|
|
}
|
|
|
|
return true;
|
|
} catch (error) {
|
|
console.error('Error in deleteTimelineEvent:', error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
// CRUD functions for IUCN assessments
|
|
|
|
export async function createIucnAssessment(assessment: Omit<Database['public']['Tables']['iucn_assessments']['Insert'], 'id'>) {
|
|
try {
|
|
const newAssessment = {
|
|
...assessment,
|
|
id: uuidv4()
|
|
};
|
|
|
|
console.log('Creating new IUCN assessment:', newAssessment);
|
|
|
|
const { data, error } = await supabase
|
|
.from('iucn_assessments')
|
|
.insert(newAssessment)
|
|
.select()
|
|
.single();
|
|
|
|
if (error) {
|
|
console.error('Error creating IUCN assessment:', error);
|
|
throw error;
|
|
}
|
|
|
|
// If this is set as latest, update other assessments to not be latest
|
|
if (newAssessment.is_latest) {
|
|
await updateIucnAssessmentsLatest(newAssessment.species_id, newAssessment.id);
|
|
}
|
|
|
|
return data;
|
|
} catch (error) {
|
|
console.error('Error in createIucnAssessment:', error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
export async function updateIucnAssessment(id: string, updates: Database['public']['Tables']['iucn_assessments']['Update']) {
|
|
try {
|
|
console.log(`Updating IUCN assessment ${id}:`, updates);
|
|
|
|
// First get the current assessment to check if we need to update latest status
|
|
const { data: currentAssessment, error: fetchError } = await supabase
|
|
.from('iucn_assessments')
|
|
.select('species_id')
|
|
.eq('id', id)
|
|
.single();
|
|
|
|
if (fetchError) {
|
|
console.error('Error fetching IUCN assessment for update:', fetchError);
|
|
throw fetchError;
|
|
}
|
|
|
|
// Update the assessment
|
|
const { data, error } = await supabase
|
|
.from('iucn_assessments')
|
|
.update(updates)
|
|
.eq('id', id)
|
|
.select()
|
|
.single();
|
|
|
|
if (error) {
|
|
console.error('Error updating IUCN assessment:', error);
|
|
throw error;
|
|
}
|
|
|
|
// If this is set as latest, update other assessments to not be latest
|
|
if (updates.is_latest && currentAssessment) {
|
|
await updateIucnAssessmentsLatest(currentAssessment.species_id, id);
|
|
}
|
|
|
|
return data;
|
|
} catch (error) {
|
|
console.error('Error in updateIucnAssessment:', error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
export async function deleteIucnAssessment(id: string) {
|
|
try {
|
|
console.log(`Deleting IUCN assessment ${id}`);
|
|
|
|
// First get the current assessment to check if we need to update latest status
|
|
const { data: currentAssessment, error: fetchError } = await supabase
|
|
.from('iucn_assessments')
|
|
.select('species_id, is_latest')
|
|
.eq('id', id)
|
|
.single();
|
|
|
|
if (fetchError) {
|
|
console.error('Error fetching IUCN assessment for deletion:', fetchError);
|
|
throw fetchError;
|
|
}
|
|
|
|
// Delete the assessment
|
|
const { error } = await supabase
|
|
.from('iucn_assessments')
|
|
.delete()
|
|
.eq('id', id);
|
|
|
|
if (error) {
|
|
console.error('Error deleting IUCN assessment:', error);
|
|
throw error;
|
|
}
|
|
|
|
// If this was the latest assessment, set another one as latest
|
|
if (currentAssessment && currentAssessment.is_latest) {
|
|
const { data: remainingAssessments, error: assessmentsError } = await supabase
|
|
.from('iucn_assessments')
|
|
.select('id')
|
|
.eq('species_id', currentAssessment.species_id)
|
|
.order('year_published', { ascending: false })
|
|
.limit(1);
|
|
|
|
if (assessmentsError) {
|
|
console.error('Error fetching remaining assessments:', assessmentsError);
|
|
} else if (remainingAssessments && remainingAssessments.length > 0) {
|
|
await updateIucnAssessment(remainingAssessments[0].id, { is_latest: true });
|
|
}
|
|
}
|
|
|
|
return true;
|
|
} catch (error) {
|
|
console.error('Error in deleteIucnAssessment:', error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
// Helper function to update latest status of IUCN assessments
|
|
async function updateIucnAssessmentsLatest(speciesId: string, latestId: string) {
|
|
try {
|
|
console.log(`Setting assessment ${latestId} as latest for species ${speciesId}`);
|
|
|
|
const { error } = await supabase
|
|
.from('iucn_assessments')
|
|
.update({ is_latest: false })
|
|
.eq('species_id', speciesId)
|
|
.neq('id', latestId);
|
|
|
|
if (error) {
|
|
console.error('Error updating IUCN assessments latest status:', error);
|
|
throw error;
|
|
}
|
|
|
|
return true;
|
|
} catch (error) {
|
|
console.error('Error in updateIucnAssessmentsLatest:', error);
|
|
throw error;
|
|
}
|
|
}
|