diff --git a/components/settings/OrganizationSettings.tsx b/components/settings/OrganizationSettings.tsx index 29c4d19..fb4f6c7 100644 --- a/components/settings/OrganizationSettings.tsx +++ b/components/settings/OrganizationSettings.tsx @@ -84,6 +84,7 @@ export default function OrganizationSettings() { const [auditTotal, setAuditTotal] = useState(0) const [isLoadingAudit, setIsLoadingAudit] = useState(false) const [auditPage, setAuditPage] = useState(0) + const [auditFetchTrigger, setAuditFetchTrigger] = useState(0) const auditPageSize = 20 const [auditActionFilter, setAuditActionFilter] = useState('') const [auditLogIdFilter, setAuditLogIdFilter] = useState('') @@ -213,16 +214,16 @@ export default function OrganizationSettings() { const timer = setTimeout(() => { setAuditPage(0) // Reset page on filter change - loadAudit() + setAuditFetchTrigger(prev => prev + 1) // Trigger fetch }, 500) return () => clearTimeout(timer) - }, [auditActionFilter, auditLogIdFilter, auditStartDate, auditEndDate, loadAudit]) + }, [auditActionFilter, auditLogIdFilter, auditStartDate, auditEndDate, activeTab]) useEffect(() => { if (activeTab === 'audit' && currentOrgId) { loadAudit() } - }, [activeTab, currentOrgId, loadAudit]) + }, [activeTab, currentOrgId, loadAudit, auditFetchTrigger]) // If no org ID, we are in personal workspace, so don't show org settings if (!currentOrgId) { diff --git a/lib/api/audit.ts b/lib/api/audit.ts index 4167cb5..2037fc0 100644 --- a/lib/api/audit.ts +++ b/lib/api/audit.ts @@ -2,7 +2,7 @@ * Audit log API client (org-scoped; requires org admin role) */ -import { API_URL } from './client' +import apiRequest from './client' export interface AuditLogEntry { id: string @@ -29,35 +29,6 @@ export interface GetAuditLogResponse { total: number } -async function auditFetch(endpoint: string, options: RequestInit = {}): Promise { - const url = `${API_URL}${endpoint}` - - const headers: HeadersInit = { - 'Content-Type': 'application/json', - ...options.headers, - } - - const response = await fetch(url, { - ...options, - headers, - credentials: 'include', - }) - - if (!response.ok) { - const errorBody = await response.json().catch(() => ({ - error: 'Unknown error', - message: `HTTP ${response.status}: ${response.statusText}`, - })) - throw new Error(errorBody.message || errorBody.error || 'Request failed') - } - - return response.json() -} - -/** - * Fetches paginated audit log entries for the current org (org from JWT; admin-only on backend). - * Normalizes response so entries is always an array (backend may return null when empty). - */ export async function getAuditLog(params: GetAuditLogParams = {}): Promise { const search = new URLSearchParams() if (params.limit != null) search.set('limit', String(params.limit)) @@ -68,7 +39,7 @@ export async function getAuditLog(params: GetAuditLogParams = {}): Promise(url, { method: 'GET' }) + const data = await apiRequest(url, { method: 'GET' }) return { entries: Array.isArray(data?.entries) ? data.entries : [], total: typeof data?.total === 'number' ? data.total : 0, diff --git a/lib/api/client.ts b/lib/api/client.ts index 27068aa..a3fcac5 100644 --- a/lib/api/client.ts +++ b/lib/api/client.ts @@ -68,7 +68,11 @@ async function apiRequest( // * Determine base URL const isAuthRequest = endpoint.startsWith('/auth') const baseUrl = isAuthRequest ? AUTH_API_URL : API_URL - const url = `${baseUrl}/api/v1${endpoint}` + + // * Handle legacy endpoints that already include /api/ prefix + const url = endpoint.startsWith('/api/') + ? `${baseUrl}${endpoint}` + : `${baseUrl}/api/v1${endpoint}` const headers: HeadersInit = { 'Content-Type': 'application/json',