fix: restore button active state + inject gangnamunni Vision data into report

- Hero button: gray when empty, accent gradient when URL entered
- generate-report: force-inject gangnamUnniStats from Vision Analysis
  into channelAnalysis (score, rating, reviews, doctors)
- Add gangnamunni Vision data to prompt context

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
claude/bold-hawking
Haewon Kam 2026-04-05 11:53:33 +09:00
parent 82e9ec6cc0
commit d1157da39c
2 changed files with 30 additions and 1 deletions

View File

@ -64,7 +64,7 @@ export default function Hero() {
className="w-full px-8 py-5 text-base font-medium bg-white/80 backdrop-blur-sm border border-slate-200 rounded-2xl focus:outline-none focus:ring-2 focus:ring-accent/20 focus:border-accent/40 shadow-sm text-center text-primary-900 placeholder:text-slate-400 transition-all group-hover:border-slate-300"
/>
</div>
<button onClick={handleAnalyze} className="w-full px-8 py-5 text-base font-bold text-white rounded-2xl transition-all shadow-xl hover:shadow-2xl flex items-center justify-center gap-3 group bg-gradient-to-r from-[#4F1DA1] to-[#021341] hover:scale-[1.02] active:scale-[0.98]">
<button onClick={handleAnalyze} className={`w-full px-8 py-5 text-base font-bold text-white rounded-2xl transition-all shadow-xl hover:shadow-2xl flex items-center justify-center gap-3 group hover:scale-[1.02] active:scale-[0.98] ${url.trim() ? 'bg-gradient-to-r from-accent to-[#021341]' : 'bg-slate-300 cursor-not-allowed'}`} disabled={!url.trim()}>
Analyze Marketing Performance
<ArrowRight className="w-5 h-5 group-hover:translate-x-1 transition-transform" />
</button>

View File

@ -156,6 +156,33 @@ ${JSON.stringify(scrapeData.branding || {}, null, 2).slice(0, 1000)}
console.log(`[report] Injected ${visionDoctors.length} doctors from Vision`);
}
// Force-inject 강남언니 data from Vision if channelAnalysis has none/zero
const guVision = vision.gangnamUnniStats as Record<string, unknown> | undefined;
if (guVision) {
report.channelAnalysis = report.channelAnalysis || {};
const existing = report.channelAnalysis.gangnamUnni;
if (!existing || existing.score === 0 || !existing.rating) {
const rating = parseFloat(String(guVision.rating || 0));
const reviewStr = String(guVision.reviews || "0").replace(/[^0-9]/g, "");
const reviews = parseInt(reviewStr) || 0;
// Score: rating 10점 만점 기준 + 리뷰 수 보정
const ratingScore = Math.min(rating * 10, 100);
const reviewBonus = Math.min(reviews / 1000, 10); // 1000리뷰당 +1, max +10
const score = Math.round(Math.min(ratingScore + reviewBonus, 100));
report.channelAnalysis.gangnamUnni = {
...(existing || {}),
score,
rating,
ratingScale: 10,
reviews,
doctors: Number(guVision.doctors) || 0,
status: "active",
recommendation: `평점 ${guVision.rating}/10, 리뷰 ${guVision.reviews}건 — 강남언니에서 활발한 활동`,
};
console.log(`[report] Injected gangnamUnni from Vision: score=${score}, rating=${rating}, reviews=${reviews}`);
}
}
// Store Vision analysis separately for frontend
report.visionAnalysis = vision;
}
@ -432,6 +459,8 @@ function buildChannelSummary(channelData: Record<string, unknown>, verified: Rec
if (ytStats) parts.push(`- YouTube (스크린샷): 구독자 ${ytStats.subscribers || '?'}, 영상 ${ytStats.videos || '?'}`);
const igStats = vision.instagramStats as Record<string, string> | undefined;
if (igStats) parts.push(`- Instagram (스크린샷): 팔로워 ${igStats.followers || '?'}, 게시물 ${igStats.posts || '?'}`);
const guStats = vision.gangnamUnniStats as Record<string, unknown> | undefined;
if (guStats) parts.push(`- 강남언니 (스크린샷): 평점 ${guStats.rating || '?'}/10, 리뷰 ${guStats.reviews || '?'}건, 의사 ${guStats.doctors || '?'}`);
}
return parts.join("\n");