diff --git a/apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/projects/page.tsx b/apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/projects/page.tsx index 5d5918a..30b7af3 100644 --- a/apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/projects/page.tsx +++ b/apps/deploy-fe/src/app/(web3-authenticated)/(dashboard)/projects/page.tsx @@ -2,12 +2,12 @@ import { PageWrapper } from '@/components/foundation' import CheckBalanceIframe from '@/components/iframe/check-balance-iframe/CheckBalanceIframe' import { FixedProjectCard } from '@/components/projects/project/ProjectCard/FixedProjectCard' -import { Button } from '@workspace/ui/components/button' -import { useEffect, useState } from 'react' -import { Shapes } from 'lucide-react' import { useGQLClient } from '@/context' import { useUser } from '@clerk/nextjs' import type { Project } from '@workspace/gql-client' +import { Button } from '@workspace/ui/components/button' +import { Shapes } from 'lucide-react' +import { useEffect, useState } from 'react' interface ProjectData { id: string @@ -24,7 +24,7 @@ export default function ProjectsPage() { const [projects, setProjects] = useState([]) const [isLoading, setIsLoading] = useState(true) const [error, setError] = useState(null) - + const client = useGQLClient() const { user } = useUser() @@ -95,7 +95,7 @@ export default function ProjectsPage() { console.log( `🔍 Project ${project.name}: repo owner = ${repoOwner}, current user = ${githubUsername}` ) - return repoOwner === githubUsername + return repoOwner.toLowerCase() === githubUsername.toLowerCase() } return true // Include projects without repository info }) @@ -130,7 +130,7 @@ export default function ProjectsPage() { setIsLoading(false) } } - + return ( Failed to load your deployed projects. Please try again.

- - + {/* Manual navigation button if auto-redirect fails */} {projectId === 'unknown-id' && (

@@ -129,4 +180,4 @@ export function SuccessStep() { ) -} \ No newline at end of file +} diff --git a/apps/deploy-fe/src/hooks/useRepoData.tsx b/apps/deploy-fe/src/hooks/useRepoData.tsx index fff00af..93c498f 100644 --- a/apps/deploy-fe/src/hooks/useRepoData.tsx +++ b/apps/deploy-fe/src/hooks/useRepoData.tsx @@ -1,8 +1,6 @@ 'use client' -import { getGitHubToken } from '@/actions/github' -import { useAuth, useUser } from '@clerk/nextjs' -import { Octokit } from '@octokit/rest' +import { useOctokit } from '@/context/OctokitContext' import { useEffect, useState } from 'react' // Define the return type of the hook @@ -22,113 +20,53 @@ export function useRepoData(repoId: string): UseRepoDataReturn { const [repoData, setRepoData] = useState(null) const [isLoading, setIsLoading] = useState(true) const [error, setError] = useState(null) - const [octokit, setOctokit] = useState(null) - // Get auth data from Clerk - const { isLoaded: isAuthLoaded, getToken, isSignedIn } = useAuth() - const { isLoaded: isUserLoaded, user } = useUser() + // Use the centralized Octokit context instead of creating our own + const { octokit, isAuth } = useOctokit() - // Initialize Octokit with the appropriate token + // Debug the context state useEffect(() => { - async function initializeOctokit() { - let token = null + console.log('🔍 useRepoData: Context state changed:', { + hasOctokit: !!octokit, + isAuth, + repoId + }) + }, [octokit, isAuth, repoId]) - // Try to get GitHub OAuth token from Clerk using multiple methods - if (isSignedIn && user) { - try { - // Check if user has connected GitHub account - const githubAccount = user.externalAccounts.find( - (account) => account.provider === 'github' - ) - - if (githubAccount) { - // Try multiple methods to get the GitHub OAuth token (same as test-connection page) - - // Method 1: Try getToken from useAuth hook - try { - token = await getToken() - console.log('Method 1 (getToken from useAuth) worked:', token ? 'SUCCESS' : 'NO TOKEN') - } catch (error) { - console.log('Method 1 failed:', error) - } - - // Method 2: Try with GitHub template parameter - if (!token) { - try { - token = await getToken({ template: 'github' }) - console.log('Method 2 (getToken with github template) worked:', token ? 'SUCCESS' : 'NO TOKEN') - } catch (error) { - console.log('Method 2 failed:', error) - } - } - - // Method 3: Try accessing window.Clerk - if (!token && typeof window !== 'undefined' && (window as any).Clerk) { - try { - token = await (window as any).Clerk.session?.getToken() - console.log('Method 3 (window.Clerk.session.getToken) worked:', token ? 'SUCCESS' : 'NO TOKEN') - } catch (error) { - console.log('Method 3 failed:', error) - } - } - - // Method 4: Try window.Clerk with GitHub template - if (!token && typeof window !== 'undefined' && (window as any).Clerk) { - try { - token = await (window as any).Clerk.session?.getToken({ template: 'github' }) - console.log('Method 4 (window.Clerk with github template) worked:', token ? 'SUCCESS' : 'NO TOKEN') - } catch (error) { - console.log('Method 4 failed:', error) - } - } - - if (token) { - console.log('Successfully obtained GitHub token from Clerk') - } else { - console.warn('All methods failed to get GitHub OAuth token from Clerk') - } - } - } catch (err) { - console.error('Error accessing Clerk user data:', err) - } - } - - // Fallback to token from environment variable - if (!token) { - token = process.env.NEXT_PUBLIC_GITHUB_FALLBACK_TOKEN || '' - if (token) { - console.warn( - 'Using fallback GitHub token. This should only be used for development.' - ) - } - } - - // Create Octokit instance with whatever token we found - if (token) { - setOctokit(new Octokit({ auth: token })) - } else { - setError('No GitHub token available') - setIsLoading(false) - } - } - - if (isAuthLoaded && isUserLoaded) { - initializeOctokit() - } - }, [isAuthLoaded, isUserLoaded, user]) - - // Fetch repo data when Octokit is available + // Fetch repo data when Octokit is available and authenticated useEffect(() => { let isMounted = true async function fetchRepoData() { - if (!octokit) { + // Don't attempt to fetch if not authenticated + if (!isAuth) { + console.log('🔍 fetchRepoData: Not authenticated, skipping fetch') + if (isMounted) { + setError('GitHub authentication required') + setRepoData(null) + setIsLoading(false) + } return } + if (!octokit) { + console.log('🔍 fetchRepoData: No octokit instance available') + if (isMounted) { + setError('GitHub client not available') + setRepoData(null) + setIsLoading(false) + } + return + } + + console.log('🔍 fetchRepoData: Starting to fetch repos...') + console.log('🔍 fetchRepoData: isAuth =', isAuth) + try { // Fetch repos from GitHub - const { data: repos } = await octokit.repos.listForAuthenticatedUser() + console.log('🔍 Making GitHub API call: octokit.rest.repos.listForAuthenticatedUser()') + const { data: repos } = await octokit.rest.repos.listForAuthenticatedUser() + console.log('🔍 GitHub API success! Received', repos.length, 'repositories') // If no repoId is provided, return all repos if (!repoId) { @@ -141,7 +79,7 @@ export function useRepoData(repoId: string): UseRepoDataReturn { } // Find the specific repo by ID if repoId is provided - const repo = repos.find((repo) => repo.id.toString() === repoId) + const repo = repos.find((repo: any) => repo.id.toString() === repoId) if (!repo) { if (isMounted) { @@ -157,7 +95,12 @@ export function useRepoData(repoId: string): UseRepoDataReturn { } } } catch (err) { - console.error('Error fetching GitHub repo:', err) + console.error('❌ Error fetching GitHub repo:', err) + console.error('❌ Error details:', { + message: err instanceof Error ? err.message : 'Unknown error', + status: (err as any)?.status, + response: (err as any)?.response?.data, + }) if (isMounted) { setError('Failed to fetch repository data') setRepoData(null) @@ -166,14 +109,19 @@ export function useRepoData(repoId: string): UseRepoDataReturn { } } - if (octokit) { + if (octokit && isAuth) { fetchRepoData() + } else if (!isAuth) { + // Handle case where we're not authenticated yet + console.log('🔍 useRepoData: Waiting for authentication...') + setIsLoading(true) + setError(null) } return () => { isMounted = false } - }, [repoId, octokit]) + }, [repoId, octokit, isAuth]) return { repoData, isLoading, error } }