164 lines
4.7 KiB
TypeScript
164 lines
4.7 KiB
TypeScript
'use client'
|
|
// src/hooks/useRepoSelection.ts
|
|
import { useState, useEffect } from 'react'
|
|
import { useOctokit } from '@/context/OctokitContext'
|
|
import { adaptRepositories, type GitHubRepo } from '../utils/typeAdapters';
|
|
|
|
interface Repository {
|
|
id: string;
|
|
name: string;
|
|
full_name: string;
|
|
default_branch: string;
|
|
html_url: string;
|
|
description?: string;
|
|
owner?: {
|
|
login: string;
|
|
avatar_url: string;
|
|
};
|
|
}
|
|
|
|
interface UseRepoSelectionResult {
|
|
repositories: Repository[];
|
|
isLoading: boolean;
|
|
error: Error | null;
|
|
fetchBranches: (repoFullName: string) => Promise<string[]>;
|
|
}
|
|
|
|
export function useRepoSelection(): UseRepoSelectionResult {
|
|
const [repositories, setRepositories] = useState<Repository[]>([])
|
|
const [isLoading, setIsLoading] = useState(true)
|
|
const [error, setError] = useState<Error | null>(null)
|
|
const { octokit, isAuth } = useOctokit()
|
|
|
|
// Fetch repositories on component mount
|
|
useEffect(() => {
|
|
const fetchRepositories = async () => {
|
|
setIsLoading(true)
|
|
setError(null)
|
|
|
|
try {
|
|
if (isAuth && octokit) {
|
|
try {
|
|
// Try to fetch repositories from GitHub
|
|
const response = await octokit.request('GET /user/repos', {
|
|
sort: 'updated',
|
|
per_page: 100
|
|
});
|
|
|
|
if (response.data && Array.isArray(response.data)) {
|
|
const repoData = response.data.map(repo => ({
|
|
id: repo.id.toString(),
|
|
name: repo.name,
|
|
full_name: repo.full_name,
|
|
default_branch: repo.default_branch,
|
|
html_url: repo.html_url,
|
|
description: repo.description,
|
|
owner: {
|
|
login: repo.owner.login,
|
|
avatar_url: repo.owner.avatar_url
|
|
}
|
|
}));
|
|
|
|
setRepositories(adaptRepositories(repoData as GitHubRepo[]));
|
|
}
|
|
} catch (err) {
|
|
console.error('Failed to fetch repositories:', err);
|
|
// Fall back to mock data
|
|
setRepositories(getMockRepositories());
|
|
}
|
|
} else {
|
|
// If not authenticated, use mock data
|
|
setRepositories(getMockRepositories());
|
|
}
|
|
} catch (err) {
|
|
const fetchError = err instanceof Error ? err : new Error('Failed to fetch repositories');
|
|
setError(fetchError);
|
|
console.error('Error in useRepoSelection hook:', fetchError);
|
|
setRepositories(getMockRepositories());
|
|
} finally {
|
|
setIsLoading(false);
|
|
}
|
|
};
|
|
|
|
fetchRepositories();
|
|
}, [octokit, isAuth]);
|
|
|
|
// Function to fetch branches for a selected repository
|
|
const fetchBranches = async (repoFullName: string): Promise<string[]> => {
|
|
if (!repoFullName) return ['main'];
|
|
|
|
try {
|
|
if (isAuth && octokit) {
|
|
const [owner, repo] = repoFullName.split('/');
|
|
if (!owner || !repo) {
|
|
throw new Error('Invalid repository format');
|
|
}
|
|
|
|
const response = await octokit.request('GET /repos/{owner}/{repo}/branches', {
|
|
owner,
|
|
repo
|
|
});
|
|
|
|
if (response.data && Array.isArray(response.data)) {
|
|
return response.data.map(branch => branch.name);
|
|
}
|
|
}
|
|
|
|
// Return mock data if unable to fetch
|
|
return ['main', 'develop', 'feature/new-ui'];
|
|
} catch (err) {
|
|
console.error('Failed to fetch branches:', err);
|
|
// Return some default branches
|
|
return ['main', 'develop', 'feature/new-ui'];
|
|
}
|
|
};
|
|
|
|
return {
|
|
repositories,
|
|
isLoading,
|
|
error,
|
|
fetchBranches
|
|
};
|
|
}
|
|
|
|
// Mock repository data for fallback
|
|
function getMockRepositories(): Repository[] {
|
|
return [
|
|
{
|
|
id: '1',
|
|
name: 'my-next-app',
|
|
full_name: 'yourusername/my-next-app',
|
|
default_branch: 'main',
|
|
html_url: 'https://github.com/yourusername/my-next-app',
|
|
description: 'A Next.js application',
|
|
owner: {
|
|
login: 'yourusername',
|
|
avatar_url: 'https://github.com/github.png'
|
|
}
|
|
},
|
|
{
|
|
id: '2',
|
|
name: 'react-portfolio',
|
|
full_name: 'yourusername/react-portfolio',
|
|
default_branch: 'master',
|
|
html_url: 'https://github.com/yourusername/react-portfolio',
|
|
description: 'Personal portfolio website',
|
|
owner: {
|
|
login: 'yourusername',
|
|
avatar_url: 'https://github.com/github.png'
|
|
}
|
|
},
|
|
{
|
|
id: '3',
|
|
name: 'node-api',
|
|
full_name: 'yourusername/node-api',
|
|
default_branch: 'main',
|
|
html_url: 'https://github.com/yourusername/node-api',
|
|
description: 'RESTful API with Node.js',
|
|
owner: {
|
|
login: 'yourusername',
|
|
avatar_url: 'https://github.com/github.png'
|
|
}
|
|
}
|
|
];
|
|
} |