Skip to content

Commit e66c78c

Browse files
committed
refactor: centralize start analysis logic and update component hooks for consistency
- Moved inline start analysis functions to a dedicated useStartAnalysis hook - Updated components to use the new hook for initiating website analysis - Removed redundant inline RPC call logic from components - Added startWebsiteAnalysis service for handling analysis start with auth check - Simplified flow by delegating start logic to shared hook, improving maintainability - Minor style adjustments and cleanup for better code organization and clarity
1 parent a72a7ca commit e66c78c

File tree

6 files changed

+122
-241
lines changed

6 files changed

+122
-241
lines changed

examples/playground/app/websites/page.tsx

Lines changed: 6 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,22 @@
11
'use client';
22

33
import { createClient } from '@/utils/supabase/client';
4-
import { useEffect, useState, useTransition } from 'react';
4+
import { useEffect, useState } from 'react';
5+
import { useStartAnalysis } from '@/lib/hooks/use-start-analysis';
56
import type { Database } from '@/supabase/functions/database-types';
67
import { Label } from '@/components/ui/label';
78
import { Input } from '@/components/ui/input';
89
import { FormMessage } from '@/components/form-message';
910
import { SubmitButton } from '@/components/submit-button';
10-
import { useRouter } from 'next/navigation';
1111
import { SkeletonTable } from '@/components/skeleton-table';
1212

1313
type WebsiteRow = Database['public']['Tables']['websites']['Row'];
1414

1515
export default function Page() {
1616
const [websites, setWebsites] = useState<WebsiteRow[] | null>(null);
17-
const [formError, setFormError] = useState<string | null>(null);
1817
const [url, setUrl] = useState('https://reddit.com/r/supabase');
19-
const [isPending, startTransition] = useTransition();
18+
const { start: startAnalysis, isPending, error: formError } = useStartAnalysis();
2019
const supabase = createClient();
21-
const router = useRouter();
2220

2321
// Process URL parameter when the component mounts
2422
useEffect(() => {
@@ -44,64 +42,12 @@ export default function Page() {
4442
}, 10);
4543
}
4644
}
47-
}, []);
45+
}, [startAnalysis]);
4846

49-
async function startAnalysis(url: string) {
50-
if (!url || isPending) {
51-
return;
52-
}
53-
54-
try {
55-
startTransition(async () => {
56-
const { data, error } = await supabase.rpc('start_analyze_website_flow', {
57-
url,
58-
});
59-
60-
if (error) {
61-
setFormError(error.message);
62-
return;
63-
}
64-
65-
if (data && data.run_id) {
66-
router.push(`/websites/runs/${data.run_id}`);
67-
} else {
68-
setFormError('Failed to start flow analysis');
69-
}
70-
});
71-
} catch (error) {
72-
setFormError('An error occurred while starting the analysis');
73-
console.error(error);
74-
}
75-
}
76-
7747
async function startAnalyzeWebsiteFlow(formData: FormData) {
7848
const url = formData.get('url') as string;
79-
80-
if (!url || isPending) {
81-
setFormError('Please enter a URL');
82-
return;
83-
}
84-
85-
try {
86-
startTransition(async () => {
87-
const { data, error } = await supabase.rpc('start_analyze_website_flow', {
88-
url,
89-
});
90-
91-
if (error) {
92-
setFormError(error.message);
93-
return;
94-
}
95-
96-
if (data && data.run_id) {
97-
router.push(`/websites/runs/${data.run_id}`);
98-
} else {
99-
setFormError('Failed to start flow analysis');
100-
}
101-
});
102-
} catch (error) {
103-
setFormError('An error occurred while starting the analysis');
104-
console.error(error);
49+
if (url) {
50+
startAnalysis(url);
10551
}
10652
}
10753

examples/playground/components/example-links.tsx

Lines changed: 5 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,73 +1,23 @@
11
'use client';
22

3-
import { useRouter } from 'next/navigation';
4-
import { useTransition, useEffect, useState } from 'react';
5-
import { createClient } from '@/utils/supabase/client';
3+
import { useStartAnalysis } from '@/lib/hooks/use-start-analysis';
64
import { exampleLinks } from '@/lib/example-links';
75
import { useLoadingState } from './loading-state-provider';
86

97
export default function ExampleLinks() {
10-
const [isPending, startTransition] = useTransition();
11-
const [isLoggedIn, setIsLoggedIn] = useState<boolean | null>(null);
12-
const router = useRouter();
13-
const supabase = createClient();
8+
const { start, isPending, error: startError } = useStartAnalysis();
149
const { setLoading } = useLoadingState();
1510

16-
useEffect(() => {
17-
supabase.auth.getUser().then(({ data }) => {
18-
setIsLoggedIn(!!data.user);
19-
});
20-
}, []);
21-
2211
// Function to handle example link clicks
2312
const handleExampleClick = (e: React.MouseEvent<HTMLAnchorElement>, url: string) => {
24-
if (isPending) {
25-
e.preventDefault();
26-
return;
27-
}
28-
2913
e.preventDefault();
30-
31-
// If user is not logged in, redirect to sign-in page
32-
if (!isLoggedIn) {
33-
console.log('User not logged in, storing URL and redirecting to sign-in:', url);
34-
localStorage.setItem('pendingAnalysisUrl', url);
35-
router.push('/sign-in');
36-
return;
37-
}
38-
39-
console.log('Starting analysis for example URL:', url);
14+
if (isPending) return;
4015

4116
// Set global loading state to true
4217
setLoading(true);
4318

44-
startTransition(async () => {
45-
try {
46-
const { data, error } = await supabase.rpc('start_analyze_website_flow', {
47-
url,
48-
});
49-
50-
if (error) {
51-
console.error('Error starting analysis:', error);
52-
setLoading(false);
53-
return;
54-
}
55-
56-
if (data && data.run_id) {
57-
console.log(
58-
'Analysis started, redirecting to:',
59-
`/websites/runs/${data.run_id}`,
60-
);
61-
router.push(`/websites/runs/${data.run_id}`);
62-
} else {
63-
console.error('No run_id returned from analysis');
64-
setLoading(false);
65-
}
66-
} catch (error) {
67-
console.error('Exception during analysis:', error);
68-
setLoading(false);
69-
}
70-
});
19+
// Start analysis will handle auth check and redirect
20+
start(url);
7121
};
7222

7323
return (

examples/playground/components/flow-run-provider.tsx

Lines changed: 4 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import { createContext, useContext, useEffect, useState, useMemo } from 'react';
44
import { useRouter } from 'next/navigation';
5+
import { useStartAnalysis } from '@/lib/hooks/use-start-analysis';
56
import {
67
fetchFlowRunData,
78
observeFlowRun,
@@ -61,12 +62,13 @@ export function FlowRunProvider({ runId, children }: FlowRunProviderProps) {
6162
const [loading, setLoading] = useState<boolean>(true);
6263
const [error, setError] = useState<string | null>(null);
6364
const [currentTime, setCurrentTime] = useState<Date>(new Date());
64-
const [analyzeLoading, setAnalyzeLoading] = useState<boolean>(false);
65-
const [analyzeError, setAnalyzeError] = useState<string | null>(null);
6665

6766
const router = useRouter();
6867
const supabase = createClient();
6968
const { setLoading: setGlobalLoading } = useLoadingState();
69+
70+
// Use the shared hook for starting analysis
71+
const { start: analyzeWebsite, isPending: analyzeLoading, error: analyzeError } = useStartAnalysis();
7072

7173
// Derive runData from the separate state pieces
7274
const runData = useMemo<ResultRow | null>(() => {
@@ -108,51 +110,6 @@ export function FlowRunProvider({ runId, children }: FlowRunProviderProps) {
108110
} as ResultRow;
109111
}, [run, stepStates, stepTasks]);
110112

111-
// Function to analyze a new website
112-
const analyzeWebsite = async (url: string) => {
113-
if (!url) {
114-
setAnalyzeError('Please enter a URL');
115-
return;
116-
}
117-
118-
setAnalyzeLoading(true);
119-
setAnalyzeError(null);
120-
121-
// Set global loading state to true
122-
setGlobalLoading(true);
123-
124-
try {
125-
console.log('Starting analysis for URL:', url);
126-
const { data, error } = await supabase.rpc('start_analyze_website_flow', {
127-
url,
128-
});
129-
130-
if (error) {
131-
console.error('Error starting analysis:', error);
132-
setAnalyzeError(error.message);
133-
setGlobalLoading(false);
134-
return;
135-
}
136-
137-
if (data && data.run_id) {
138-
console.log(
139-
'Analysis started, redirecting to:',
140-
`/websites/runs/${data.run_id}`,
141-
);
142-
router.push(`/websites/runs/${data.run_id}`);
143-
} else {
144-
console.error('No run_id returned from analysis');
145-
setAnalyzeError('Failed to start flow analysis');
146-
setGlobalLoading(false);
147-
}
148-
} catch (error) {
149-
setAnalyzeError('An error occurred while starting the analysis');
150-
console.error('Exception during analysis:', error);
151-
setGlobalLoading(false);
152-
} finally {
153-
setAnalyzeLoading(false);
154-
}
155-
};
156113

157114

158115
useEffect(() => {
Lines changed: 10 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -1,96 +1,35 @@
11
'use client';
22

3-
import { useRouter } from 'next/navigation';
4-
import { useState, useTransition, useEffect } from 'react';
3+
import { useStartAnalysis } from '@/lib/hooks/use-start-analysis';
54
import { Label } from '@/components/ui/label';
65
import { Input } from '@/components/ui/input';
76
import { FormMessage } from '@/components/form-message';
87
import { SubmitButton } from '@/components/submit-button';
9-
import { createClient } from '@/utils/supabase/client';
108
import { useLoadingState } from './loading-state-provider';
119

1210
export default function WebsiteAnalyzerForm() {
13-
const [formError, setFormError] = useState<string | null>(null);
14-
const [isPending, startTransition] = useTransition();
15-
const [isLoggedIn, setIsLoggedIn] = useState<boolean | null>(null);
16-
const router = useRouter();
17-
const supabase = createClient();
11+
const { start: startAnalysis, isPending, error: formError } = useStartAnalysis();
1812
const { setLoading } = useLoadingState();
1913

20-
useEffect(() => {
21-
supabase.auth.getUser().then(({ data }) => {
22-
setIsLoggedIn(!!data.user);
23-
});
24-
}, []);
25-
2614
async function handleAnalyzeWebsite(formData: FormData) {
2715
const url = formData.get('url') as string;
28-
29-
if (!url) {
30-
setFormError('Please enter a URL');
31-
return;
32-
}
33-
34-
// If user is not logged in, redirect to sign-in page
35-
if (!isLoggedIn) {
36-
console.log(
37-
'User not logged in, storing URL and redirecting to sign-in:',
38-
url,
39-
);
40-
// Store the URL in localStorage to redirect back after login
41-
localStorage.setItem('pendingAnalysisUrl', url);
42-
router.push('/sign-in');
43-
return;
44-
}
45-
16+
4617
if (!url) {
47-
setFormError('Please enter a URL');
4818
return;
4919
}
50-
51-
try {
52-
console.log('Starting analysis for URL:', url);
53-
// Set global loading state to true
54-
setLoading(true);
55-
56-
// Start the transition to show loading state
57-
startTransition(async () => {
58-
const { data, error } = await supabase.rpc('start_analyze_website_flow', {
59-
url,
60-
});
61-
62-
if (error) {
63-
console.error('Error starting analysis:', error);
64-
setFormError(error.message);
65-
setLoading(false);
66-
return;
67-
}
68-
69-
if (data && data.run_id) {
70-
console.log(
71-
'Analysis started, redirecting to:',
72-
`/websites/runs/${data.run_id}`,
73-
);
74-
router.push(`/websites/runs/${data.run_id}`);
75-
} else {
76-
console.error('No run_id returned from analysis');
77-
setFormError('Failed to start flow analysis');
78-
setLoading(false);
79-
}
80-
});
81-
} catch (error) {
82-
setFormError('An error occurred while starting the analysis');
83-
console.error('Exception during analysis:', error);
84-
setLoading(false);
85-
}
20+
21+
// Set global loading state to true
22+
setLoading(true);
23+
24+
// Start analysis will handle auth check and redirect
25+
startAnalysis(url);
8626
}
8727

8828
return (
8929
<div className="flex flex-col w-full p-4 gap-4 border rounded-lg shadow-sm">
9030
<h2 className="text-2xl font-medium">Analyze a Website</h2>
9131
<p className="text-sm text-foreground/60">
9232
Enter a URL to analyze a website
93-
{!isLoggedIn && " (you'll need to sign in first)"}
9433
</p>
9534
<form action={handleAnalyzeWebsite} className="flex flex-col gap-4">
9635
<div>
@@ -106,18 +45,10 @@ export default function WebsiteAnalyzerForm() {
10645
/>
10746
</div>
10847
<SubmitButton disabled={isPending} pendingText="🔄 Starting analysis...">
109-
{isLoggedIn ? '🚀 Start Analysis' : 'Sign in & Analyze'}
48+
🚀 Start Analysis
11049
</SubmitButton>
11150
{formError && <FormMessage message={{ error: formError }} />}
11251
</form>
113-
{isLoggedIn === false && (
114-
<div className="mt-4 p-4 bg-yellow-50 border border-yellow-200 rounded-md">
115-
<p className="text-yellow-800">
116-
You'll need to sign in to analyze websites. When you click the
117-
button, you'll be redirected to the sign-in page.
118-
</p>
119-
</div>
120-
)}
12152
</div>
12253
);
12354
}

0 commit comments

Comments
 (0)