fix: remove tenant switcher from TopBar, fix aiProactive API double-prefix

- Remove tenant switcher dropdown from TopBar (cleanup unused vars/imports)
- Fix aiProactive.ts: remove /api/v1 prefix from apiClient calls (baseURL already includes it)
- This fixes 404 errors on /api/v1/api/v1/ai-proactive/suggestions
This commit is contained in:
Agent Zero
2026-07-19 00:28:11 +02:00
parent ef6d011e16
commit 5d9ddbebd2
2 changed files with 5 additions and 65 deletions
+5 -5
View File
@@ -21,7 +21,7 @@ export function useSuggestions() {
useEffect(() => {
// Initial load
apiClient.get('/api/v1/ai-proactive/suggestions').then(r => {
apiClient.get('/ai-proactive/suggestions').then(r => {
setSuggestions(r.data.items);
}).catch(() => {});
@@ -41,11 +41,11 @@ export function useSuggestions() {
const dismiss = useCallback(async (id: string) => {
setSuggestions(prev => prev.filter(s => s.id !== id));
await apiClient.post(`/api/v1/ai-proactive/suggestions/${id}/dismiss`).catch(() => {});
await apiClient.post(`/ai-proactive/suggestions/${id}/dismiss`).catch(() => {});
}, []);
const act = useCallback(async (id: string, actionIndex: number) => {
const result = await apiClient.post(`/api/v1/ai-proactive/suggestions/${id}/act`, {
const result = await apiClient.post(`/ai-proactive/suggestions/${id}/act`, {
action_index: actionIndex
});
setSuggestions(prev => prev.map(s => s.id === id ? { ...s, is_acted_upon: true } : s));
@@ -59,11 +59,11 @@ export function useProactiveSettings() {
const [settings, setSettings] = useState<any>(null);
useEffect(() => {
apiClient.get('/api/v1/ai-proactive/settings').then(r => setSettings(r.data));
apiClient.get('/ai-proactive/settings').then(r => setSettings(r.data));
}, []);
const update = useCallback(async (updates: any) => {
const r = await apiClient.put('/api/v1/ai-proactive/settings', updates);
const r = await apiClient.put('/ai-proactive/settings', updates);
setSettings(r.data);
return r.data;
}, []);
-60
View File
@@ -4,7 +4,6 @@ import { useNavigate } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
import { useAuthStore } from '@/store/authStore';
import { useUIStore } from '@/store/uiStore';
import { useTenant } from '@/hooks/useTenant';
import { useLogout } from '@/api/hooks';
import { Avatar } from '@/components/ui/Avatar';
import { Badge } from '@/components/ui/Badge';
@@ -16,19 +15,15 @@ export function TopBar() {
const navigate = useNavigate();
const { user } = useAuthStore();
const { toggleSidebar, openAISidebarProactive } = useUIStore();
const { currentTenant, availableTenants, switchTenant, isSwitching } = useTenant();
const logoutMutation = useLogout();
const [tenantMenuOpen, setTenantMenuOpen] = useState(false);
const [userMenuOpen, setUserMenuOpen] = useState(false);
const [notifOpen, setNotifOpen] = useState(false);
const tenantRef = useRef<HTMLDivElement>(null);
const userRef = useRef<HTMLDivElement>(null);
const notifRef = useRef<HTMLDivElement>(null);
useEffect(() => {
const handleClickOutside = (e: MouseEvent) => {
if (tenantRef.current && !tenantRef.current.contains(e.target as Node)) setTenantMenuOpen(false);
if (userRef.current && !userRef.current.contains(e.target as Node)) setUserMenuOpen(false);
if (notifRef.current && !notifRef.current.contains(e.target as Node)) setNotifOpen(false);
};
@@ -45,11 +40,6 @@ export function TopBar() {
navigate('/login');
};
const handleTenantSwitch = async (tenantId: string) => {
await switchTenant(tenantId);
setTenantMenuOpen(false);
};
const fullName = user ? `${user.first_name} ${user.last_name}` : '';
return (
@@ -70,56 +60,6 @@ export function TopBar() {
</svg>
</button>
{/* Tenant switcher */}
<div ref={tenantRef} className="relative">
<button
onClick={() => setTenantMenuOpen(!tenantMenuOpen)}
className="flex items-center gap-2 px-3 py-2 rounded-md hover:bg-secondary-100 min-h-touch focus:outline-none focus-visible:ring-2 focus-visible:ring-primary-500"
aria-label={t('topbar.switchTenant')}
aria-expanded={tenantMenuOpen}
aria-haspopup="listbox"
>
<svg className="w-4 h-4 text-secondary-500" fill="none" viewBox="0 0 24 24" stroke="currentColor" aria-hidden="true">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 21V5a2 2 0 00-2-2H7a2 2 0 00-2 2v16m14 0h2m-2 0h-5m-9 0H3m2 0h5M9 7h1m-1 4h1m4-4h1m-1 4h1m-5 10v-5a1 1 0 011-1h2a1 1 0 011 1v5m-4 0h4" />
</svg>
<span className="text-sm font-medium text-secondary-700 max-w-32 truncate">
{currentTenant?.name || t('topbar.tenant')}
</span>
<svg className="w-4 h-4 text-secondary-400" fill="none" viewBox="0 0 24 24" stroke="currentColor" aria-hidden="true">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 9l-7 7-7-7" />
</svg>
</button>
{tenantMenuOpen && (
<ul
className="absolute top-full left-0 mt-1 w-56 bg-white rounded-md shadow-lg border border-secondary-200 py-1 z-50"
role="listbox"
aria-label={t('topbar.switchTenant')}
>
{availableTenants.map((tenant) => (
<li key={tenant.id}>
<button
onClick={() => handleTenantSwitch(tenant.id)}
className={clsx(
'w-full text-left px-3 py-2 text-sm hover:bg-secondary-50 min-h-touch flex items-center justify-between focus:outline-none focus-visible:ring-2 focus-visible:ring-primary-500',
tenant.id === currentTenant?.id && 'bg-primary-50 text-primary-700'
)}
role="option"
aria-selected={tenant.id === currentTenant?.id}
disabled={isSwitching}
>
{tenant.name}
{tenant.id === currentTenant?.id && (
<svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" aria-hidden="true">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 13l4 4L19 7" />
</svg>
)}
</button>
</li>
))}
</ul>
)}
</div>
{/* Search */}
<div className="hidden md:block">
<SearchDropdown placeholder={t('topbar.search')} />