SECTION C — Message Quality & Vocabulary
@if(!empty($attempt->review_data['nlp_analysis']['sentiment_arc']))
@php
$sentimentData = $attempt->review_data['nlp_analysis']['sentiment_arc'];
$width = 600;
$height = 160;
$paddingTop = 20;
$paddingRight = 20;
$paddingBottom = 30;
$paddingLeft = 40;
$chartW = $width - $paddingLeft - $paddingRight;
$chartH = $height - $paddingTop - $paddingBottom;
// Reconstruct sentences from transcript for older reviews that lack `sentence`
$transcriptSentences = [];
$rawTranscript = trim((string) ($attempt->transcript ?? ''));
if ($rawTranscript !== '') {
$current = '';
$chars = preg_split('//u', $rawTranscript, -1, PREG_SPLIT_NO_EMPTY) ?: [];
$length = count($chars);
for ($i = 0; $i < $length; $i++) {
$current .= $chars[$i];
if ($chars[$i] === '!' || $chars[$i] === '?') {
$trimmed = trim(rtrim(trim($current), '.!?'));
if ($trimmed !== '') {
$transcriptSentences[] = $trimmed;
}
$current = '';
} elseif ($chars[$i] === '.') {
$pre = rtrim($current, '.');
$parts = preg_split('/\s+/', trim($pre)) ?: [];
$lastWord = $parts ? (string) end($parts) : '';
$beforeIsSingleUpper = mb_strlen($lastWord) === 1 && preg_match('/^[A-Z]$/u', $lastWord);
$afterIsDigit = ($i + 1 < $length) && ctype_digit($chars[$i + 1]);
if (! $beforeIsSingleUpper && ! $afterIsDigit) {
$trimmed = trim(rtrim(trim($current), '.'));
if ($trimmed !== '') {
$transcriptSentences[] = $trimmed;
}
$current = '';
}
}
}
$remainder = trim(rtrim(trim($current), '.!?'));
if ($remainder !== '') {
$transcriptSentences[] = $remainder;
}
$allWords = preg_split('/\s+/', $rawTranscript) ?: [];
if (count($transcriptSentences) <= 1 && count($allWords) > 15) {
$transcriptSentences = [];
for ($j = 0; $j < count($allWords); $j += 12) {
$transcriptSentences[] = implode(' ', array_slice($allWords, $j, 12));
}
}
}
$points = [];
$path = '';
$positiveStatements = [];
$negativeStatements = [];
foreach ($sentimentData as $index => $point) {
$x = $paddingLeft + ($index / max(count($sentimentData) - 1, 1)) * $chartW;
$score = (float)($point['score'] ?? 0.5);
$label = strtoupper($point['label'] ?? 'NEUTRAL');
$sentenceIndex = (int) ($point['sentence_index'] ?? $index);
$sentenceText = trim((string) ($point['sentence'] ?? ($transcriptSentences[$sentenceIndex] ?? '')));
$val = 0;
if ($label === 'POSITIVE') {
$val = max(0.0, $score - 0.5) * 2;
if ($sentenceText !== '') {
$positiveStatements[] = $sentenceText;
}
} elseif ($label === 'NEGATIVE') {
$val = -max(0.0, $score - 0.5) * 2;
if ($sentenceText !== '') {
$negativeStatements[] = $sentenceText;
}
}
$y = $paddingTop + $chartH / 2 - ($val * $chartH / 2);
$points[] = [
'x' => $x,
'y' => $y,
'label' => $label,
'score' => $score
];
$path .= ($index === 0 ? 'M' : 'L') . " {$x} {$y} ";
}
$positiveStatements = array_values(array_unique($positiveStatements));
$negativeStatements = array_values(array_unique($negativeStatements));
@endphp
Sentiment Arc / Pitch Tone Trajectory
POS
NEU
NEG
@if($path)
@endif
@foreach($points as $p)
@php
$color = 'var(--text-dim)';
if ($p['label'] === 'POSITIVE') $color = 'var(--accent)';
elseif ($p['label'] === 'NEGATIVE') $color = 'var(--red)';
@endphp
@endforeach
@foreach($points as $index => $p)
@if($index % 4 === 0)
S{{ $index + 1 }}
@endif
@endforeach
Positive Statements ({{ count($positiveStatements) }})
@forelse($positiveStatements as $statement)
"{{ $statement }}"
@empty
[ No positive statements detected ]
@endforelse
Negative Statements ({{ count($negativeStatements) }})
@forelse($negativeStatements as $statement)
"{{ $statement }}"
@empty
[ No negative statements detected ]
@endforelse
@endif
Detected Power Words
@forelse($powerWords as $powerWord)
{{ $powerWord }}
@empty
[ No power words detected ]
@endforelse
Top Informative Keywords
@forelse($topKeywords as $kw)
{{ $kw }}
@empty
[ No keywords detected ]
@endforelse
@if(!empty($salesConcepts))
Sales Concept Coverage Details
@foreach($salesConcepts as $concept)
{{ !empty($concept['detected']) ? '[X]' : '[ ]' }} {{ $concept['concept'] ?? 'Concept' }}
@if(!empty($concept['detected']) && isset($concept['confidence']))
{{ round($concept['confidence'] * 100) }}% confidence
@endif
@if(!empty($concept['detected']) && !empty($concept['evidence_sentence']))
"{{ $concept['evidence_sentence'] }}"
@endif
@endforeach
@endif