import { supabase } from '../db/client.js';
import type {
ListPalettesResponse,
PaletteDetailsResponse,
DesignPalette
} from '../types.js';
/**
* List all available design palettes
*/
export async function listPalettes(): Promise<ListPalettesResponse> {
try {
const client = supabase.getAnonClient();
const { data, error, count } = await client
.from('design_palettes')
.select(`
id,
name,
category,
mood,
industries
`, { count: 'exact' })
.order('name');
if (error) {
supabase.log(`Error fetching palettes: ${error.message}`, 'error');
throw new Error(`Failed to fetch palettes: ${error.message}`);
}
if (!data) {
return { palettes: [], total: 0 };
}
const palettes = data.map(palette => ({
id: palette.id,
name: palette.name,
category: palette.category,
mood: palette.mood || [],
industries: palette.industries || []
}));
supabase.log(`Retrieved ${palettes.length} palettes`);
return {
palettes,
total: count || palettes.length
};
} catch (error) {
supabase.log(`Error in listPalettes: ${error}`, 'error');
throw error;
}
}
/**
* Get detailed information about a specific palette
*/
export async function getPaletteDetails(paletteId: string): Promise<PaletteDetailsResponse> {
try {
if (!paletteId) {
throw new Error('Palette ID is required');
}
const client = supabase.getAnonClient();
const { data, error } = await client
.from('design_palettes')
.select('*')
.eq('id', paletteId)
.single();
if (error) {
if (error.code === 'PGRST116') {
throw new Error(`Palette with ID '${paletteId}' not found`);
}
supabase.log(`Error fetching palette details: ${error.message}`, 'error');
throw new Error(`Failed to fetch palette details: ${error.message}`);
}
if (!data) {
throw new Error(`Palette with ID '${paletteId}' not found`);
}
const palette = data as DesignPalette;
supabase.log(`Retrieved details for palette: ${palette.name}`);
return {
id: palette.id,
name: palette.name,
category: palette.category,
mood: palette.mood || [],
industries: palette.industries || [],
colors: {
primaryLight: palette.primary_light,
primaryDark: palette.primary_dark,
accentLight: palette.accent_light
},
typography: {
heading: palette.heading_font,
body: palette.body_font
},
borderRadius: palette.border_radius
};
} catch (error) {
supabase.log(`Error in getPaletteDetails: ${error}`, 'error');
throw error;
}
}
/**
* Search palettes by category, mood, or industry
*/
export async function searchPalettes(params: {
category?: string;
mood?: string;
industry?: string;
limit?: number;
}): Promise<ListPalettesResponse> {
try {
const client = supabase.getAnonClient();
const { category, mood, industry, limit = 50 } = params;
let query = client
.from('design_palettes')
.select(`
id,
name,
category,
mood,
industries
`, { count: 'exact' });
// Apply filters
if (category) {
query = query.eq('category', category);
}
if (mood) {
query = query.contains('mood', [mood]);
}
if (industry) {
query = query.contains('industries', [industry]);
}
const { data, error, count } = await query
.order('name')
.limit(limit);
if (error) {
supabase.log(`Error searching palettes: ${error.message}`, 'error');
throw new Error(`Failed to search palettes: ${error.message}`);
}
if (!data) {
return { palettes: [], total: 0 };
}
const palettes = data.map(palette => ({
id: palette.id,
name: palette.name,
category: palette.category,
mood: palette.mood || [],
industries: palette.industries || []
}));
supabase.log(`Found ${palettes.length} palettes matching criteria`);
return {
palettes,
total: count || palettes.length
};
} catch (error) {
supabase.log(`Error in searchPalettes: ${error}`, 'error');
throw error;
}
}