mono/packages/ui/src/components/ImageWizard/handlers/dataHandlers.ts
2026-01-20 10:34:09 +01:00

194 lines
5.6 KiB
TypeScript

import { ImageFile } from '../types';
import { supabase } from '@/integrations/supabase/client';
import { toast } from 'sonner';
import { translate } from '@/i18n';
import { Logger } from '../utils/logger';
/**
* Data Loading & Saving Handlers
* - Load/save presets
* - Load/save workflows
* - Load/save templates
* - Load/save quick actions
* - Load/save history
* - Load family versions
* - Load available images
*/
export const loadFamilyVersions = async (
parentImages: ImageFile[],
setImages: React.Dispatch<React.SetStateAction<ImageFile[]>>,
logger: Logger
) => {
try {
// Get all parent IDs and image IDs to find complete families
const imageIds = parentImages.map(img => img.realDatabaseId || img.id).filter(id => id && id.match(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i));
if (imageIds.length === 0) {
return;
}
// For each image, find its complete family tree
const allFamilyImages = new Set<string>();
for (const imageId of imageIds) {
// First, get the current image details to check if it has a parent
const { data: currentImage, error: currentError } = await supabase
.from('pictures')
.select('id, parent_id')
.eq('id', imageId)
.single();
if (currentError) {
console.error('🔧 [Wizard] Error loading current image:', currentError);
continue;
}
// Determine the root of the family tree
let rootId = currentImage.parent_id || imageId;
// Load all versions in this family (root + all children)
const { data: familyVersions, error: familyError } = await supabase
.from('pictures')
.select(`
id,
title,
image_url,
user_id,
parent_id,
description,
is_selected,
created_at
`)
.or(`id.eq.${rootId},parent_id.eq.${rootId}`)
.order('created_at', { ascending: true });
if (familyError) {
console.error('🔧 [Wizard] Error loading family versions:', familyError);
continue;
}
// Add all family members to our set (excluding the initial image)
familyVersions?.forEach(version => {
if (version.id !== imageId) {
allFamilyImages.add(version.id);
}
});
}
// Now fetch all the unique family images
if (allFamilyImages.size > 0) {
const { data: versions, error } = await supabase
.from('pictures')
.select(`
id,
title,
image_url,
user_id,
parent_id,
description,
is_selected,
created_at
`)
.in('id', Array.from(allFamilyImages))
.order('created_at', { ascending: true });
if (error) throw error;
const versionImages: ImageFile[] = versions?.map(version => ({
id: version.id,
src: version.image_url,
title: version.title,
userId: version.user_id,
selected: false, // Default to not selected in UI
isPreferred: version.is_selected || false,
isGenerated: true,
aiText: version.description || undefined
})) || [];
// Add versions to images, but also update existing images with correct selection status
setImages(prev => {
// Create a map of database selection status
const dbSelectionStatus = new Map();
// Check if this is a singleton family (only one version)
const isSingleton = versions?.length === 1;
versions?.forEach(version => {
// If explicitly selected in DB, OR if it's the only version in the family
const isPreferred = version.is_selected || (isSingleton && !version.parent_id);
dbSelectionStatus.set(version.id, isPreferred);
});
// Update existing images and add new ones
const existingIds = new Set(prev.map(img => img.id));
const updatedExisting = prev.map(img => {
if (dbSelectionStatus.has(img.id)) {
const dbSelected = dbSelectionStatus.get(img.id);
return { ...img, isPreferred: dbSelected };
}
return img;
});
// Add new images
const newImages = versionImages.filter(img => !existingIds.has(img.id)).map(img => {
if (dbSelectionStatus.has(img.id)) {
return { ...img, isPreferred: dbSelectionStatus.get(img.id) };
}
return img;
});
const finalImages = [...updatedExisting, ...newImages];
return finalImages;
});
}
} catch (error) {
console.error('🔧 [Wizard] Error loading family versions:', error);
toast.error(translate('Failed to load image versions'));
}
};
export const loadAvailableImages = async (
setAvailableImages: React.Dispatch<React.SetStateAction<ImageFile[]>>,
setLoadingImages: React.Dispatch<React.SetStateAction<boolean>>
) => {
setLoadingImages(true);
try {
// Load images from all users (public images)
const { data: pictures, error } = await supabase
.from('pictures')
.select(`
id,
title,
image_url,
user_id
`)
.order('created_at', { ascending: false })
.limit(50);
if (error) throw error;
const imageFiles: ImageFile[] = pictures?.map(picture => ({
id: picture.id,
src: picture.image_url,
title: picture.title,
userId: picture.user_id,
selected: false
})) || [];
setAvailableImages(imageFiles);
} catch (error) {
console.error('Error loading images:', error);
toast.error(translate('Failed to load images'));
} finally {
setLoadingImages(false);
}
};