feat: implement customizable funnel stages per tenant
- Modified attendances.funnel_stage in DB from ENUM to VARCHAR. - Created tenant_funnels table and backend API routes to manage custom stages. - Added /admin/funnels page for Admins/Managers to create, edit, order, and color-code their funnel stages. - Updated Dashboard, UserDetail, and AttendanceDetail to fetch and render dynamic funnel stages instead of hardcoded enums. - Added defensive checks and logging to GET /users/:idOrSlug to fix sporadic 500 errors during impersonation handoffs.
This commit is contained in:
@@ -82,6 +82,60 @@ export const clearAllNotifications = async (): Promise<boolean> => {
|
||||
}
|
||||
};
|
||||
|
||||
// --- Funnels Functions ---
|
||||
export const getFunnels = async (tenantId: string): Promise<any[]> => {
|
||||
try {
|
||||
const response = await fetch(`${API_URL}/funnels?tenantId=${tenantId}`, {
|
||||
headers: getHeaders()
|
||||
});
|
||||
if (!response.ok) throw new Error('Falha ao buscar funis');
|
||||
return await response.json();
|
||||
} catch (error) {
|
||||
console.error("API Error (getFunnels):", error);
|
||||
return [];
|
||||
}
|
||||
};
|
||||
|
||||
export const createFunnel = async (data: any): Promise<any> => {
|
||||
const response = await fetch(`${API_URL}/funnels`, {
|
||||
method: 'POST',
|
||||
headers: getHeaders(),
|
||||
body: JSON.stringify(data)
|
||||
});
|
||||
if (!response.ok) {
|
||||
const error = await response.json();
|
||||
throw new Error(error.error || 'Erro ao criar funil');
|
||||
}
|
||||
return await response.json();
|
||||
};
|
||||
|
||||
export const updateFunnel = async (id: string, data: any): Promise<boolean> => {
|
||||
try {
|
||||
const response = await fetch(`${API_URL}/funnels/${id}`, {
|
||||
method: 'PUT',
|
||||
headers: getHeaders(),
|
||||
body: JSON.stringify(data)
|
||||
});
|
||||
return response.ok;
|
||||
} catch (error) {
|
||||
console.error("API Error (updateFunnel):", error);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
export const deleteFunnel = async (id: string): Promise<boolean> => {
|
||||
try {
|
||||
const response = await fetch(`${API_URL}/funnels/${id}`, {
|
||||
method: 'DELETE',
|
||||
headers: getHeaders()
|
||||
});
|
||||
return response.ok;
|
||||
} catch (error) {
|
||||
console.error("API Error (deleteFunnel):", error);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
export const searchGlobal = async (query: string): Promise<{ members: User[], teams: any[], attendances: any[], organizations?: any[] }> => {
|
||||
try {
|
||||
const response = await fetch(`${API_URL}/search?q=${encodeURIComponent(query)}`, {
|
||||
|
||||
Reference in New Issue
Block a user