// src/components/TextPanel.jsx
import React from 'react'
import { EMOTION_COLORS } from '../lib/api'
const EMOTION_ORDER = ['Happy', 'Angry', 'Fear', 'Sad', 'Neutral', 'Surprised', 'Disgust']
export default function TextPanel({ result, inputText }) {
const probs = result?.text_probs || {}
const sentiment = result?.sentiment_score ?? null
const keywords = result?.keywords || []
const emotion = result?.text_emotion || '—'
const sentimentLabel =
sentiment === null ? '—'
: sentiment > 0.6 ? 'Positive'
: sentiment < 0.4 ? 'Negative'
: 'Neutral'
const sentimentColor =
sentiment === null ? '#5e82aa'
: sentiment > 0.6 ? '#30d988'
: sentiment < 0.4 ? '#ff4d6a'
: '#5e82aa'
return (
NLP Sentiment Analysis
RoBERTa-base
{/* Input text preview with keyword highlights */}
{inputText ? renderKeywords(inputText, keywords) : (
Awaiting text input…
)}
{/* Sentiment score */}
Sentiment
{sentiment !== null ? `${(sentiment * 100).toFixed(0)}% ${sentimentLabel}` : '—'}
{/* Emotion probability bars */}
{EMOTION_ORDER.map(name => {
const val = probs[name] ?? 0
const color = EMOTION_COLORS[name]
const isTop = name === emotion
return (
{name}
{(val * 100).toFixed(0)}%
)
})}
)
}
function renderKeywords(text, keywords) {
if (!keywords || keywords.length === 0) return text
const SENTIMENT_COLORS = { pos: '#30d988', neg: '#ff6b77', neu: '#5e82aa' }
const parts = []
let remaining = text
keywords.forEach(([kw, sentiment]) => {
const idx = remaining.toLowerCase().indexOf(kw.toLowerCase())
if (idx === -1) return
if (idx > 0) parts.push(remaining.slice(0, idx))
parts.push(
{remaining.slice(idx, idx + kw.length)}
)
remaining = remaining.slice(idx + kw.length)
})
if (remaining) parts.push(remaining)
return parts
}