mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-20 15:31:13 -05:00
feat: Implement photo processing logic
This commit is contained in:
@@ -186,7 +186,7 @@ export async function approveSubmissionItems(
|
||||
entityId = await createRideModel(item.item_data, dependencyMap);
|
||||
break;
|
||||
case 'photo':
|
||||
entityId = await approvePhotos(item.item_data, dependencyMap);
|
||||
entityId = await approvePhotos(item.item_data, dependencyMap, userId, item.submission_id);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -396,18 +396,157 @@ async function createRideModel(data: any, dependencyMap: Map<string, string>): P
|
||||
return model.id;
|
||||
}
|
||||
|
||||
async function approvePhotos(data: any, dependencyMap: Map<string, string>): Promise<string> {
|
||||
async function approvePhotos(data: any, dependencyMap: Map<string, string>, userId: string, submissionId: string): Promise<string> {
|
||||
// Photos are already uploaded to Cloudflare
|
||||
// Resolve dependencies for entity associations
|
||||
const resolvedData = resolveDependencies(data, dependencyMap);
|
||||
|
||||
// For now, return the first photo URL
|
||||
// In the future, this could create photo records in a dedicated table
|
||||
if (resolvedData.photos && Array.isArray(resolvedData.photos) && resolvedData.photos.length > 0) {
|
||||
return resolvedData.photos[0].url;
|
||||
if (!resolvedData.photos || !Array.isArray(resolvedData.photos) || resolvedData.photos.length === 0) {
|
||||
throw new Error('No photos found in submission');
|
||||
}
|
||||
|
||||
const { entity_id, context, park_id, ride_id, company_id } = resolvedData;
|
||||
|
||||
return '';
|
||||
// Determine entity_id and entity_type
|
||||
let finalEntityId = entity_id;
|
||||
let entityType = context;
|
||||
|
||||
// Support legacy field names
|
||||
if (!finalEntityId) {
|
||||
if (park_id) {
|
||||
finalEntityId = park_id;
|
||||
entityType = 'park';
|
||||
} else if (ride_id) {
|
||||
finalEntityId = ride_id;
|
||||
entityType = 'ride';
|
||||
} else if (company_id) {
|
||||
finalEntityId = company_id;
|
||||
// Need to determine company type from database
|
||||
}
|
||||
}
|
||||
|
||||
if (!finalEntityId || !entityType) {
|
||||
throw new Error('Missing entity_id or context in photo submission');
|
||||
}
|
||||
|
||||
// Insert photos into the photos table
|
||||
const photosToInsert = resolvedData.photos.map((photo: any, index: number) => {
|
||||
// Extract CloudFlare image ID from URL if not provided
|
||||
let cloudflareImageId = photo.cloudflare_image_id;
|
||||
if (!cloudflareImageId && photo.url) {
|
||||
// URL format: https://imagedelivery.net/{account_hash}/{image_id}/{variant}
|
||||
const urlParts = photo.url.split('/');
|
||||
cloudflareImageId = urlParts[urlParts.length - 2];
|
||||
}
|
||||
|
||||
return {
|
||||
cloudflare_image_id: cloudflareImageId,
|
||||
cloudflare_image_url: photo.url,
|
||||
entity_type: entityType,
|
||||
entity_id: finalEntityId,
|
||||
title: photo.title || resolvedData.title,
|
||||
caption: photo.caption,
|
||||
photographer_credit: photo.photographer_credit,
|
||||
date_taken: photo.date || photo.date_taken,
|
||||
order_index: photo.order !== undefined ? photo.order : index,
|
||||
is_featured: index === 0, // First photo is featured by default
|
||||
submission_id: submissionId,
|
||||
submitted_by: userId,
|
||||
approved_by: userId,
|
||||
approved_at: new Date().toISOString(),
|
||||
};
|
||||
});
|
||||
|
||||
const { data: insertedPhotos, error } = await supabase
|
||||
.from('photos')
|
||||
.insert(photosToInsert)
|
||||
.select();
|
||||
|
||||
if (error) {
|
||||
console.error('Error inserting photos:', error);
|
||||
throw new Error(`Database error: ${error.message}`);
|
||||
}
|
||||
|
||||
// Update entity's featured image if this is the first photo
|
||||
if (insertedPhotos && insertedPhotos.length > 0) {
|
||||
const firstPhoto = insertedPhotos[0];
|
||||
await updateEntityFeaturedImage(
|
||||
entityType,
|
||||
finalEntityId,
|
||||
firstPhoto.cloudflare_image_url,
|
||||
firstPhoto.cloudflare_image_id
|
||||
);
|
||||
}
|
||||
|
||||
// Return the first photo URL for backwards compatibility
|
||||
return resolvedData.photos[0].url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update entity's featured image fields
|
||||
*/
|
||||
async function updateEntityFeaturedImage(
|
||||
entityType: string,
|
||||
entityId: string,
|
||||
imageUrl: string,
|
||||
imageId: string
|
||||
): Promise<void> {
|
||||
try {
|
||||
// Update based on entity type
|
||||
if (entityType === 'park') {
|
||||
const { data: existingPark } = await supabase
|
||||
.from('parks')
|
||||
.select('card_image_url')
|
||||
.eq('id', entityId)
|
||||
.single();
|
||||
|
||||
if (existingPark && !existingPark.card_image_url) {
|
||||
await supabase
|
||||
.from('parks')
|
||||
.update({
|
||||
card_image_url: imageUrl,
|
||||
card_image_id: imageId,
|
||||
updated_at: new Date().toISOString(),
|
||||
})
|
||||
.eq('id', entityId);
|
||||
}
|
||||
} else if (entityType === 'ride') {
|
||||
const { data: existingRide } = await supabase
|
||||
.from('rides')
|
||||
.select('card_image_url')
|
||||
.eq('id', entityId)
|
||||
.single();
|
||||
|
||||
if (existingRide && !existingRide.card_image_url) {
|
||||
await supabase
|
||||
.from('rides')
|
||||
.update({
|
||||
card_image_url: imageUrl,
|
||||
card_image_id: imageId,
|
||||
updated_at: new Date().toISOString(),
|
||||
})
|
||||
.eq('id', entityId);
|
||||
}
|
||||
} else if (['manufacturer', 'operator', 'designer', 'property_owner'].includes(entityType)) {
|
||||
const { data: existingCompany } = await supabase
|
||||
.from('companies')
|
||||
.select('logo_url')
|
||||
.eq('id', entityId)
|
||||
.single();
|
||||
|
||||
if (existingCompany && !existingCompany.logo_url) {
|
||||
await supabase
|
||||
.from('companies')
|
||||
.update({
|
||||
logo_url: imageUrl,
|
||||
updated_at: new Date().toISOString(),
|
||||
})
|
||||
.eq('id', entityId);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`Error updating ${entityType} featured image:`, error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user