import { writable } from 'svelte/store'; import { supabase } from './supabaseClient.js'; import { currentUser } from './auth.js'; // The family currently being managed — an owner has exactly one (their own), // an agent may have several and switches between them here. export const activeFamilyId = writable(localStorage.getItem('nf.activeFamilyId') || null); activeFamilyId.subscribe(id => { if (id) localStorage.setItem('nf.activeFamilyId', id); }); export async function createFamily(name) { const user = currentUser(); if (!user) throw new Error('Not signed in'); const { data: fam, error: famErr } = await supabase .from('nf_families') .insert({ name, owner_id: user.id }) .select() .single(); if (famErr) throw famErr; const { error: memErr } = await supabase.from('nf_family_members').insert({ family_id: fam.id, user_id: user.id, invited_email: user.email, role: 'owner', status: 'active' }); if (memErr) throw memErr; activeFamilyId.set(fam.id); return fam; } /** List every family this user belongs to, owner or agent, with their role. */ export async function listMyFamilies() { const user = currentUser(); if (!user) return []; const { data, error } = await supabase .from('nf_family_members') .select('role, status, family_id, nf_families(id, name)') .eq('user_id', user.id) .eq('status', 'active'); if (error) throw error; return (data || []).map(r => ({ id: r.family_id, name: r.nf_families?.name, role: r.role })); } /** Pending invites addressed to this user's email, not yet accepted. */ export async function listPendingInvites() { const user = currentUser(); if (!user) return []; const { data, error } = await supabase .from('nf_family_members') .select('id, role, family_id, nf_families(name)') .eq('invited_email', user.email) .eq('status', 'invited'); if (error) throw error; return (data || []).map(r => ({ membershipId: r.id, familyId: r.family_id, familyName: r.nf_families?.name, role: r.role })); } export async function acceptInvite(membershipId) { const user = currentUser(); if (!user) throw new Error('Not signed in'); const { error } = await supabase .from('nf_family_members') .update({ user_id: user.id, status: 'active' }) .eq('id', membershipId); if (error) throw error; } /** Owner invites an agent by email — creates a pending membership row. */ export async function inviteAgent(familyId, email) { const { error } = await supabase.from('nf_family_members').insert({ family_id: familyId, invited_email: email, role: 'agent', status: 'invited' }); if (error) throw error; } export async function listFamilyMembers(familyId) { const { data, error } = await supabase .from('nf_family_members') .select('id, invited_email, role, status') .eq('family_id', familyId); if (error) throw error; return data || []; } export async function removeMember(membershipId) { const { error } = await supabase.from('nf_family_members').delete().eq('id', membershipId); if (error) throw error; } export function getActiveFamilyId() { let id; activeFamilyId.subscribe(v => id = v)(); return id; }