feat: Add Magic UI components including DotPattern, RainbowButton, ShineBorder, WordRotate, and BlurIn, along with corresponding Tailwind configuration updates.
This commit is contained in:
@@ -39,7 +39,7 @@ export async function POST(request: NextRequest) {
|
||||
const { analysis } = bodySchema.parse(body)
|
||||
|
||||
console.log(`🔍 Finding opportunities for: ${analysis.productName}`)
|
||||
|
||||
|
||||
// Sort queries by priority
|
||||
const sortedQueries = analysis.dorkQueries
|
||||
.sort((a, b) => {
|
||||
@@ -49,14 +49,14 @@ export async function POST(request: NextRequest) {
|
||||
.slice(0, 15) // Limit to top 15 queries
|
||||
|
||||
const allResults: SearchResult[] = []
|
||||
|
||||
|
||||
// Execute searches
|
||||
for (const query of sortedQueries) {
|
||||
try {
|
||||
console.log(` Searching: ${query.query.substring(0, 60)}...`)
|
||||
const results = await searchGoogle(query.query, 5)
|
||||
allResults.push(...results)
|
||||
|
||||
|
||||
// Small delay to avoid rate limiting
|
||||
await new Promise(r => setTimeout(r, 500))
|
||||
} catch (e) {
|
||||
@@ -85,7 +85,7 @@ export async function POST(request: NextRequest) {
|
||||
|
||||
} catch (error: any) {
|
||||
console.error('❌ Search error:', error)
|
||||
|
||||
|
||||
return NextResponse.json(
|
||||
{ error: error.message || 'Failed to find opportunities' },
|
||||
{ status: 500 }
|
||||
@@ -136,15 +136,15 @@ async function searchDirect(query: string, num: number): Promise<SearchResult[]>
|
||||
|
||||
const html = await response.text()
|
||||
const results: SearchResult[] = []
|
||||
|
||||
|
||||
// Simple regex parsing
|
||||
const resultBlocks = html.match(/<div class="g"[^>]*>([\s\S]*?)<\/div>\s*<\/div>/g) || []
|
||||
|
||||
|
||||
for (const block of resultBlocks.slice(0, num)) {
|
||||
const titleMatch = block.match(/<h3[^>]*>(.*?)<\/h3>/)
|
||||
const linkMatch = block.match(/<a href="([^"]+)"/)
|
||||
const snippetMatch = block.match(/<div class="VwiC3b[^"]*"[^>]*>(.*?)<\/div>/)
|
||||
|
||||
|
||||
if (titleMatch && linkMatch) {
|
||||
results.push({
|
||||
title: titleMatch[1].replace(/<[^>]+>/g, ''),
|
||||
@@ -169,7 +169,7 @@ function getSource(url: string): string {
|
||||
}
|
||||
|
||||
async function analyzeOpportunities(
|
||||
results: SearchResult[],
|
||||
results: SearchResult[],
|
||||
analysis: EnhancedProductAnalysis
|
||||
): Promise<Opportunity[]> {
|
||||
const opportunities: Opportunity[] = []
|
||||
@@ -181,17 +181,17 @@ async function analyzeOpportunities(
|
||||
|
||||
// Calculate relevance score
|
||||
const content = (result.title + ' ' + result.snippet).toLowerCase()
|
||||
|
||||
|
||||
// Match keywords
|
||||
const matchedKeywords = analysis.keywords
|
||||
.filter(k => content.includes(k.term.toLowerCase()))
|
||||
.map(k => k.term)
|
||||
|
||||
|
||||
// Match problems
|
||||
const matchedProblems = analysis.problemsSolved
|
||||
.filter(p => content.includes(p.problem.toLowerCase()))
|
||||
.map(p => p.problem)
|
||||
|
||||
|
||||
// Calculate score
|
||||
const keywordScore = Math.min(matchedKeywords.length * 0.15, 0.6)
|
||||
const problemScore = Math.min(matchedProblems.length * 0.2, 0.4)
|
||||
@@ -210,7 +210,7 @@ async function analyzeOpportunities(
|
||||
}
|
||||
|
||||
// Find matching persona
|
||||
const matchedPersona = analysis.personas.find(p =>
|
||||
const matchedPersona = analysis.personas.find(p =>
|
||||
p.searchBehavior.some(b => content.includes(b.toLowerCase()))
|
||||
)?.name
|
||||
|
||||
|
||||
Reference in New Issue
Block a user