import { supabase } from './supabase'; async function fbCall(method, action, body = null) { const { data: { session } } = await supabase.auth.getSession(); if (!session?.access_token) return; await fetch(`/api/filebrowser?action=${action}`, { method, headers: { Authorization: `Bearer ${session.access_token}`, 'Content-Type': 'application/json', }, body: body ? JSON.stringify(body) : undefined, }).catch(() => {}); } // Create /Clients/{name}/ folder. Silently fails if already exists. export async function createClientFolder(companyName) { if (!companyName) return; await fbCall('POST', 'mkdir', { path: '/', name: 'Clients' }); await fbCall('POST', 'mkdir', { path: '/Clients', name: companyName }); } // Rename /Clients/{oldName} → /Clients/{newName} export async function renameClientFolder(oldName, newName) { if (!oldName || !newName || oldName === newName) return; await fbCall('POST', 'rename', { path: `/Clients/${oldName}`, name: newName }); } // Same safeName logic as the server (api/filebrowser.js) function safeName(v) { return String(v || '').trim() .replace(/[\\/:*?"<>|#%{}^~[\]`]+/g, '-') .replace(/\s+/g, ' ') .replace(/^-+|-+$/g, ''); } // Upload files to the correct Request Info/{rev} folder in FileBrowser. // companyName is required. versionNumber defaults to 0 (R00). // Best-effort — call with .catch(() => {}) so failures don't block submission. export async function uploadFilesToRequestInfo(files, companyName, projectName, taskTitle, versionNumber = 0) { if (!files?.length || !companyName || !projectName || !taskTitle) return; const { data: { session } } = await supabase.auth.getSession(); if (!session?.access_token) return; const authHeader = `Bearer ${session.access_token}`; // Determine role const { data: profile } = await supabase.from('profiles').select('role').eq('id', session.user.id).single(); const role = profile?.role; const co = safeName(companyName); const proj = safeName(projectName); const task = safeName(taskTitle); const rev = `R${String(versionNumber).padStart(2, '0')}`; // Build virtual path segments for mkdir. // Clients: virtual root is per-company; company folder already exists — start one level in. // Team/external: full path under /Clients/{co}/... let mkdirs; let revPath; if (role === 'client') { revPath = `/${co}/Projects/${proj}/${task}/Request Info/${rev}`; mkdirs = [ { path: `/${co}`, name: 'Projects' }, { path: `/${co}/Projects`, name: proj }, { path: `/${co}/Projects/${proj}`, name: task }, { path: `/${co}/Projects/${proj}/${task}`, name: 'Request Info' }, { path: `/${co}/Projects/${proj}/${task}/Request Info`, name: rev }, ]; } else { revPath = `/Clients/${co}/Projects/${proj}/${task}/Request Info/${rev}`; mkdirs = [ { path: '/Clients', name: co }, { path: `/Clients/${co}`, name: 'Projects' }, { path: `/Clients/${co}/Projects`, name: proj }, { path: `/Clients/${co}/Projects/${proj}`, name: task }, { path: `/Clients/${co}/Projects/${proj}/${task}`, name: 'Request Info' }, { path: `/Clients/${co}/Projects/${proj}/${task}/Request Info`, name: rev }, ]; } for (const seg of mkdirs) { await fetch('/api/filebrowser?action=mkdir', { method: 'POST', headers: { Authorization: authHeader, 'Content-Type': 'application/json' }, body: JSON.stringify(seg), }).catch(() => {}); } // Get upload token for the revision folder const tokenRes = await fetch('/api/filebrowser?action=upload-token', { method: 'POST', headers: { Authorization: authHeader, 'Content-Type': 'application/json' }, body: JSON.stringify({ path: revPath }), }).catch(() => null); if (!tokenRes?.ok) return; const { token, url, fbPath } = await tokenRes.json(); if (!token || !url || !fbPath) return; for (const file of files) { await fetch(`${url}/api/resources?source=files&path=${encodeURIComponent(`${fbPath}/${file.name}`)}&override=true`, { method: 'POST', headers: { Authorization: `Bearer ${token}`, 'Content-Type': file.type || 'application/octet-stream' }, body: file, }).catch(() => {}); } } // Create missing /Clients/{name}/ folders for all companies. export async function backfillClientFolders() { const { data } = await supabase.from('companies').select('name'); if (!data?.length) return; await fbCall('POST', 'mkdir', { path: '/', name: 'Clients' }); for (const company of data) { if (company.name) await fbCall('POST', 'mkdir', { path: '/Clients', name: company.name }); } }