Skip to content

Commit dc5e82c

Browse files
authored
Merge pull request wishonia#205 from mikepsinn/ResearchForm
Refactor Researcher page with new components
2 parents fa21ca1 + f98baa6 commit dc5e82c

File tree

3 files changed

+124
-109
lines changed

3 files changed

+124
-109
lines changed
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
'use client'
2+
3+
import { useState } from 'react'
4+
import { useRouter } from 'next/navigation'
5+
import { useSession } from 'next-auth/react'
6+
import { Button } from "@/components/ui/button"
7+
import { Input } from "@/components/ui/input"
8+
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/ui/card"
9+
import { ArticleWithRelations } from '@/lib/agents/researcher/researcher'
10+
import GlobalBrainNetwork from "@/components/landingPage/global-brain-network"
11+
import ArticleRenderer from '@/components/ArticleRenderer'
12+
import { findOrCreateArticleByTopic } from "@/app/researcher/researcherActions"
13+
14+
interface ResearchFormProps {
15+
initialTopic?: string
16+
onTopicChange: (topic: string) => void
17+
}
18+
19+
export default function ResearchForm({ initialTopic = '', onTopicChange }: ResearchFormProps) {
20+
const { data: session } = useSession()
21+
const router = useRouter()
22+
23+
const [article, setArticle] = useState<ArticleWithRelations | null>(null)
24+
const [error, setError] = useState('')
25+
const [isGenerating, setIsGenerating] = useState(false)
26+
const [topic, setTopic] = useState(initialTopic)
27+
28+
async function handleSubmit(submittedTopic: string) {
29+
if (!session?.user?.id) {
30+
router.push('/auth/signin')
31+
return
32+
}
33+
34+
if (!submittedTopic) {
35+
setError('Please enter a topic')
36+
return
37+
}
38+
39+
setIsGenerating(true)
40+
setError('')
41+
42+
try {
43+
const generatedArticle = await findOrCreateArticleByTopic(submittedTopic, session.user.id)
44+
setArticle(generatedArticle)
45+
onTopicChange(submittedTopic)
46+
} catch (err) {
47+
setError('Failed to generate article. Please try again.')
48+
} finally {
49+
setIsGenerating(false)
50+
}
51+
}
52+
53+
return (
54+
<>
55+
<Card className="mb-8">
56+
<CardHeader>
57+
<CardTitle>Autonomous Research Agent</CardTitle>
58+
<CardDescription>
59+
Enter a topic for me to research and I'll write an article with sources!
60+
</CardDescription>
61+
</CardHeader>
62+
<CardContent>
63+
<form onSubmit={(e) => {
64+
e.preventDefault()
65+
handleSubmit(topic)
66+
}} className="flex gap-4">
67+
<Input
68+
type="text"
69+
value={topic}
70+
onChange={(e) => setTopic(e.target.value)}
71+
placeholder="Enter article topic"
72+
className="flex-grow"
73+
/>
74+
<Button type="submit" disabled={isGenerating}>
75+
{isGenerating ? 'Researching...' : 'Start Researching'}
76+
</Button>
77+
</form>
78+
</CardContent>
79+
{error && (
80+
<CardFooter>
81+
<p className="text-red-500">{error}</p>
82+
</CardFooter>
83+
)}
84+
</Card>
85+
{isGenerating && (
86+
<div className="w-4/5 max-w-[600px] h-[600px] mx-auto">
87+
<GlobalBrainNetwork />
88+
</div>
89+
)}
90+
{!isGenerating && article && <ArticleRenderer article={article} currentUserId={session?.user?.id} />}
91+
</>
92+
)
93+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
'use client'
2+
3+
import { useSearchParams, useRouter } from 'next/navigation'
4+
import ResearchForm from './ResearchForm'
5+
import ArticleSearchAndGrid from '@/components/article/ArticleSearchAndGrid'
6+
7+
export function ResearchPageContent() {
8+
const searchParams = useSearchParams()
9+
const router = useRouter()
10+
const initialTopic = searchParams?.get('q') || ''
11+
12+
const handleTopicChange = (topic: string) => {
13+
router.push(`?q=${encodeURIComponent(topic)}`, { scroll: false })
14+
}
15+
16+
return (
17+
<main className="container mx-auto p-4">
18+
<ResearchForm
19+
initialTopic={initialTopic}
20+
onTopicChange={handleTopicChange}
21+
/>
22+
<ArticleSearchAndGrid />
23+
</main>
24+
)
25+
}

app/researcher/page.tsx

Lines changed: 6 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -1,111 +1,8 @@
1-
'use client'
2-
export const maxDuration = 60;
1+
import { requireAuth } from '@/lib/auth'
2+
import { ResearchPageContent } from './components/ResearchPageContent'
33

4-
import { useState, useEffect } from 'react'
5-
import { useSearchParams, useRouter } from 'next/navigation'
6-
import { useSession } from 'next-auth/react' // Import useSession from next-auth
7-
import ArticleRenderer from '@/components/ArticleRenderer'
8-
import { Button } from "@/components/ui/button"
9-
import { Input } from "@/components/ui/input"
10-
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/ui/card"
11-
import { ArticleWithRelations } from '@/lib/agents/researcher/researcher'
12-
import GlobalBrainNetwork from "@/components/landingPage/global-brain-network"
13-
import { findOrCreateArticleByTopic } from "@/app/researcher/researcherActions";
14-
import { UserAuthForm } from '@/components/user/user-auth-form'
15-
import ArticleSearchAndGrid from '@/components/article/ArticleSearchAndGrid';
16-
17-
export default function ResearcherPage() {
18-
const { data: session, status } = useSession()
19-
const loading = status === "loading"
20-
const router = useRouter()
21-
const searchParams = useSearchParams()
22-
23-
const [article, setArticle] = useState<ArticleWithRelations | null>(null)
24-
const [error, setError] = useState('')
25-
const [isGenerating, setIsGenerating] = useState(false)
26-
const [topic, setTopic] = useState('')
27-
28-
29-
useEffect(() => {
30-
const queryTopic = searchParams?.get('q')
31-
if (queryTopic) {
32-
setTopic(queryTopic)
33-
handleSubmit(queryTopic)
34-
}
35-
}, [searchParams])
36-
37-
async function handleSubmit(submittedTopic: string) {
38-
39-
if (!session?.user?.id) {
40-
return <UserAuthForm />
41-
}
42-
43-
if (!submittedTopic) {
44-
setError('Please enter a topic')
45-
return
46-
}
47-
48-
setIsGenerating(true)
49-
setError('')
50-
51-
try {
52-
const generatedArticle = await findOrCreateArticleByTopic(submittedTopic, session?.user?.id)
53-
setArticle(generatedArticle)
54-
router.push(`?q=${encodeURIComponent(submittedTopic)}`, { scroll: false })
55-
} catch (err) {
56-
setError('Failed to generate article. Please try again.')
57-
} finally {
58-
setIsGenerating(false)
59-
}
60-
}
61-
62-
if (loading) {
63-
return <div>Loading...</div>
64-
}
65-
66-
if (!session?.user?.id) {
67-
return <UserAuthForm />
68-
}
69-
70-
return (
71-
<main className="container mx-auto p-4">
72-
<Card className="mb-8">
73-
<CardHeader>
74-
<CardTitle>Autonomous Research Agent</CardTitle>
75-
<CardDescription>
76-
Enter a topic for me to research and I'll write an article with sources!
77-
</CardDescription>
78-
</CardHeader>
79-
<CardContent>
80-
<form onSubmit={(e) => {
81-
e.preventDefault()
82-
handleSubmit(topic)
83-
}} className="flex gap-4">
84-
<Input
85-
type="text"
86-
value={topic}
87-
onChange={(e) => setTopic(e.target.value)}
88-
placeholder="Enter article topic"
89-
className="flex-grow"
90-
/>
91-
<Button type="submit" disabled={isGenerating}>
92-
{isGenerating ? 'Researching...' : 'Start Researching'}
93-
</Button>
94-
</form>
95-
</CardContent>
96-
{error && (
97-
<CardFooter>
98-
<p className="text-red-500">{error}</p>
99-
</CardFooter>
100-
)}
101-
</Card>
102-
{isGenerating && (
103-
<div className="w-4/5 max-w-[600px] h-[600px] mx-auto">
104-
<GlobalBrainNetwork />
105-
</div>
106-
)}
107-
{!isGenerating && article && <ArticleRenderer article={article} currentUserId={session?.user?.id} />}
108-
<ArticleSearchAndGrid />
109-
</main>
110-
)
4+
export default async function ResearcherPage() {
5+
await requireAuth("/researcher")
6+
7+
return <ResearchPageContent />
1118
}

0 commit comments

Comments
 (0)