All checks were successful
Build & Push / build-and-push (push) Successful in 6m2s
- Site analysis: cheerio HTML parsing, inline tech stack detection (~20 CMS/framework/analytics signatures), Google PageSpeed API integration - Gemini Live voice agent: WebSocket-based real-time voice mode with live transcript, selection chips, and mid-conversation website analysis - Type/Talk mode toggle with silent capability detection - Stepped progress animation during brief generation (4 animated steps) - URL + thoughts fields in Step 2, phone + contact preference in Step 3 - AI prompt improvements: dedicated website analysis section, 30-min call, concrete benefits, industry depth - Email redesign: branded templates with logo, proper markdown rendering for both client and admin - French locale support for AI-generated briefs - Smaller checkmark, compact booking CTA, expanded brief area Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
54 lines
2.2 KiB
TypeScript
54 lines
2.2 KiB
TypeScript
import { NextRequest, NextResponse } from 'next/server';
|
|
import { analyzeSite, type SiteAnalysis } from '@/lib/site-analysis';
|
|
|
|
// ─── Summary Builder ──────────────────────────────────────────────────────────
|
|
|
|
function buildAnalysisSummary(a: SiteAnalysis): string {
|
|
if (a.fetchError) return "I wasn't able to reach that site to analyze it.";
|
|
|
|
const parts: string[] = [];
|
|
|
|
if (a.techStack?.cms) parts.push(`it's built on ${a.techStack.cms}`);
|
|
if (a.techStack?.framework) parts.push(`using ${a.techStack.framework}`);
|
|
if (a.techStack?.ecommerce) parts.push(`with ${a.techStack.ecommerce} for e-commerce`);
|
|
|
|
if (a.performance) {
|
|
const score = a.performance.score;
|
|
const quality = score >= 90 ? 'excellent' : score >= 50 ? 'moderate' : 'low';
|
|
parts.push(`the mobile performance score is ${score} out of 100, which is ${quality}`);
|
|
}
|
|
|
|
if (a.techStack?.hosting) parts.push(`hosted on ${a.techStack.hosting}`);
|
|
if (a.hasForms) parts.push('it has contact forms');
|
|
|
|
if (a.techStack?.analytics && a.techStack.analytics.length > 0) {
|
|
parts.push(`using ${a.techStack.analytics.join(' and ')} for analytics`);
|
|
}
|
|
|
|
if (parts.length === 0) {
|
|
return "I was able to fetch the site but couldn't determine much about its technology stack.";
|
|
}
|
|
|
|
return `Here's what I found: ${parts.join(', ')}.`;
|
|
}
|
|
|
|
// ─── Route Handler ────────────────────────────────────────────────────────────
|
|
|
|
export async function POST(request: NextRequest) {
|
|
try {
|
|
const { url } = (await request.json()) as { url?: string };
|
|
|
|
if (!url?.trim()) {
|
|
return NextResponse.json({ success: false, error: 'URL required' }, { status: 400 });
|
|
}
|
|
|
|
const analysis = await analyzeSite(url.trim());
|
|
const summary = buildAnalysisSummary(analysis);
|
|
|
|
return NextResponse.json({ success: true, summary, analysis });
|
|
} catch (error) {
|
|
console.error('[analyze-site] Failed:', error);
|
|
return NextResponse.json({ success: false, error: 'Analysis failed' }, { status: 500 });
|
|
}
|
|
}
|