157 lines
5.5 KiB
TypeScript
157 lines
5.5 KiB
TypeScript
import { supabase as defaultSupabase } from "@/integrations/supabase/client";
|
|
import { SupabaseClient } from "@supabase/supabase-js";
|
|
import { fetchWithDeduplication } from "@/lib/db";
|
|
|
|
export const createLayout = async (layoutData: any, client?: SupabaseClient) => {
|
|
const supabase = client || defaultSupabase;
|
|
const { data: sessionData } = await supabase.auth.getSession();
|
|
const token = sessionData.session?.access_token;
|
|
|
|
const headers: HeadersInit = {
|
|
'Content-Type': 'application/json'
|
|
};
|
|
if (token) headers['Authorization'] = `Bearer ${token}`;
|
|
|
|
const res = await fetch(`/api/layouts`, {
|
|
method: 'POST',
|
|
headers,
|
|
body: JSON.stringify(layoutData)
|
|
});
|
|
|
|
if (!res.ok) {
|
|
throw new Error(`Failed to create layout: ${res.statusText}`);
|
|
}
|
|
|
|
return await res.json();
|
|
};
|
|
|
|
export const getLayout = async (layoutId: string, client?: SupabaseClient) => {
|
|
const key = `layout-${layoutId}`;
|
|
return fetchWithDeduplication(key, async () => {
|
|
const supabase = client || defaultSupabase;
|
|
const { data: sessionData } = await supabase.auth.getSession();
|
|
const token = sessionData.session?.access_token;
|
|
|
|
const headers: HeadersInit = {
|
|
'Content-Type': 'application/json'
|
|
};
|
|
if (token) headers['Authorization'] = `Bearer ${token}`;
|
|
|
|
const res = await fetch(`/api/layouts/${layoutId}`, {
|
|
method: 'GET',
|
|
headers
|
|
});
|
|
|
|
if (!res.ok) {
|
|
throw new Error(`Failed to fetch layout: ${res.statusText}`);
|
|
}
|
|
|
|
// Wrap in object to match Supabase response format { data, error }
|
|
const data = await res.json();
|
|
return { data, error: null };
|
|
});
|
|
};
|
|
|
|
export const getLayouts = async (filters?: { type?: string, visibility?: string, limit?: number, offset?: number }, client?: SupabaseClient) => {
|
|
const params = new URLSearchParams();
|
|
if (filters?.type) params.append('type', filters.type);
|
|
if (filters?.visibility) params.append('visibility', filters.visibility);
|
|
if (filters?.limit) params.append('limit', filters.limit.toString());
|
|
if (filters?.offset) params.append('offset', filters.offset.toString());
|
|
|
|
const key = `layouts-${params.toString()}`;
|
|
return fetchWithDeduplication(key, async () => {
|
|
const supabase = client || defaultSupabase;
|
|
const { data: sessionData } = await supabase.auth.getSession();
|
|
const token = sessionData.session?.access_token;
|
|
|
|
const headers: HeadersInit = {
|
|
'Content-Type': 'application/json'
|
|
};
|
|
if (token) headers['Authorization'] = `Bearer ${token}`;
|
|
|
|
const res = await fetch(`/api/layouts?${params.toString()}`, {
|
|
method: 'GET',
|
|
headers
|
|
});
|
|
|
|
if (!res.ok) {
|
|
throw new Error(`Failed to fetch layouts: ${res.statusText}`);
|
|
}
|
|
|
|
// Wrap in object to match Supabase response format { data, error }
|
|
const data = await res.json();
|
|
return { data, error: null };
|
|
});
|
|
};
|
|
export const updateLayoutMeta = async (layoutId: string, metaUpdates: any) => {
|
|
// Fetch current layout to merge meta
|
|
const { data: sessionData } = await defaultSupabase.auth.getSession();
|
|
const token = sessionData.session?.access_token;
|
|
const headers: HeadersInit = { 'Content-Type': 'application/json' };
|
|
if (token) headers['Authorization'] = `Bearer ${token}`;
|
|
|
|
// Get current layout
|
|
const getRes = await fetch(`/api/layouts/${layoutId}`, { headers });
|
|
if (!getRes.ok) throw new Error(`Failed to fetch layout: ${getRes.statusText}`);
|
|
const layout = await getRes.json();
|
|
|
|
const currentMeta = (layout?.meta as any) || {};
|
|
const newMeta = { ...currentMeta, ...metaUpdates };
|
|
|
|
// Update layout with merged meta
|
|
const updateRes = await fetch(`/api/layouts/${layoutId}`, {
|
|
method: 'PATCH',
|
|
headers,
|
|
body: JSON.stringify({ meta: newMeta })
|
|
});
|
|
|
|
if (!updateRes.ok) throw new Error(`Failed to update layout meta: ${updateRes.statusText}`);
|
|
return await updateRes.json();
|
|
};
|
|
export const updateLayout = async (layoutId: string, layoutData: any, client?: SupabaseClient) => {
|
|
const supabase = client || defaultSupabase;
|
|
const { data: sessionData } = await supabase.auth.getSession();
|
|
const token = sessionData.session?.access_token;
|
|
|
|
const headers: HeadersInit = {
|
|
'Content-Type': 'application/json'
|
|
};
|
|
if (token) headers['Authorization'] = `Bearer ${token}`;
|
|
|
|
const res = await fetch(`/api/layouts/${layoutId}`, {
|
|
method: 'PATCH',
|
|
headers,
|
|
body: JSON.stringify(layoutData)
|
|
});
|
|
|
|
if (!res.ok) {
|
|
throw new Error(`Failed to update layout: ${res.statusText}`);
|
|
}
|
|
|
|
return await res.json();
|
|
};
|
|
|
|
|
|
export const deleteLayout = async (layoutId: string, client?: SupabaseClient) => {
|
|
const supabase = client || defaultSupabase;
|
|
const { data: sessionData } = await supabase.auth.getSession();
|
|
const token = sessionData.session?.access_token;
|
|
|
|
const headers: HeadersInit = {
|
|
'Content-Type': 'application/json'
|
|
};
|
|
if (token) headers['Authorization'] = `Bearer ${token}`;
|
|
|
|
const res = await fetch(`/api/layouts/${layoutId}`, {
|
|
method: 'DELETE',
|
|
headers
|
|
});
|
|
|
|
if (!res.ok) {
|
|
throw new Error(`Failed to delete layout: ${res.statusText}`);
|
|
}
|
|
|
|
return true;
|
|
};
|