import { Skeleton } from '@/components/skeleton'; import { Badge } from '@/components/ui/badge'; import { Button } from '@/components/ui/button'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from '@/components/ui/select'; import { useAppParams } from '@/hooks/use-app-params'; import { useTRPC } from '@/integrations/trpc/react'; import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; import { createFileRoute } from '@tanstack/react-router'; import { formatDistanceToNow } from 'date-fns'; import { CheckCircleIcon, Loader2Icon, XCircleIcon } from 'lucide-react'; import { useState } from 'react'; import { toast } from 'sonner'; export const Route = createFileRoute( '/_app/$organizationId/$projectId/settings/_tabs/gsc' )({ component: GscSettings, }); function GscSettings() { const { projectId } = useAppParams(); const trpc = useTRPC(); const queryClient = useQueryClient(); const [selectedSite, setSelectedSite] = useState(''); const connectionQuery = useQuery( trpc.gsc.getConnection.queryOptions( { projectId }, { refetchInterval: 5000 } ) ); const sitesQuery = useQuery( trpc.gsc.getSites.queryOptions( { projectId }, { enabled: !!connectionQuery.data && !connectionQuery.data.siteUrl } ) ); const initiateOAuth = useMutation( trpc.gsc.initiateOAuth.mutationOptions({ onSuccess: (data) => { // Route through the API /gsc/initiate endpoint which sets cookies then redirects to Google const apiUrl = (import.meta.env.VITE_API_URL as string) ?? ''; const initiateUrl = new URL(`${apiUrl}/gsc/initiate`); initiateUrl.searchParams.set('state', data.state); initiateUrl.searchParams.set('code_verifier', data.codeVerifier); initiateUrl.searchParams.set('project_id', data.projectId); initiateUrl.searchParams.set('redirect', data.url); window.location.href = initiateUrl.toString(); }, onError: () => { toast.error('Failed to initiate Google Search Console connection'); }, }) ); const selectSite = useMutation( trpc.gsc.selectSite.mutationOptions({ onSuccess: () => { toast.success('Site connected', { description: 'Backfill of 6 months of data has started.', }); queryClient.invalidateQueries(trpc.gsc.getConnection.pathFilter()); }, onError: () => { toast.error('Failed to select site'); }, }) ); const disconnect = useMutation( trpc.gsc.disconnect.mutationOptions({ onSuccess: () => { toast.success('Disconnected from Google Search Console'); queryClient.invalidateQueries(trpc.gsc.getConnection.pathFilter()); }, onError: () => { toast.error('Failed to disconnect'); }, }) ); const connection = connectionQuery.data; if (connectionQuery.isLoading) { return (
Connect your Google Search Console property to import search performance data.
You will be redirected to Google to authorize access. Only read-only access to Search Console data is requested.
Choose which Google Search Console property to connect to this project.
No Search Console properties found for this Google account.
) : ( <> > )}Connected to Google Search Console.