39948-vm/frontend/src/components/Assets/ProjectSelector.tsx

83 lines
2.2 KiB
TypeScript

import axios from 'axios';
import { useRouter } from 'next/router';
import { useCallback, useEffect, useMemo, useState } from 'react';
import { logger } from '../../lib/logger';
export type Project = {
id: string;
name: string;
};
interface UseProjectSelectorOptions {
currentUser: unknown;
}
interface UseProjectSelectorReturn {
projects: Project[];
selectedProjectId: string;
isLoadingProjects: boolean;
selectedProjectName: string;
}
export function useProjectSelector({
currentUser,
}: UseProjectSelectorOptions): UseProjectSelectorReturn {
const router = useRouter();
const routeProjectId = useMemo(() => {
const value = router.query.projectId;
if (Array.isArray(value)) return value[0] || '';
return String(value || '');
}, [router.query.projectId]);
const [projects, setProjects] = useState<Project[]>([]);
const [isLoadingProjects, setIsLoadingProjects] = useState(false);
// Redirect if no projectId in URL
useEffect(() => {
if (!router.isReady) return;
if (!routeProjectId) {
router.replace('/projects/projects-list');
}
}, [router.isReady, routeProjectId, router]);
const loadProjects = useCallback(async () => {
setIsLoadingProjects(true);
try {
const response = await axios.get(
'/projects?limit=100&page=0&sort=desc&field=updatedAt',
);
const rows = Array.isArray(response?.data?.rows)
? response.data.rows
: [];
setProjects(rows);
} catch (error: unknown) {
const errorMessage =
error instanceof Error ? error.message : String(error);
logger.error('Failed to load projects:', { error: errorMessage });
setProjects([]);
} finally {
setIsLoadingProjects(false);
}
}, []);
useEffect(() => {
if (!currentUser) return;
loadProjects();
}, [currentUser, loadProjects]);
const selectedProjectName = useMemo(() => {
return projects.find((p) => p.id === routeProjectId)?.name || '';
}, [projects, routeProjectId]);
return {
projects,
selectedProjectId: routeProjectId, // Direct from URL - no fallback
isLoadingProjects,
selectedProjectName,
};
}
export default useProjectSelector;