mono/packages/ui/src/modules/layout/client-layouts.ts
2026-02-25 10:11:54 +01:00

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;
};