feat: add Legal Translation tool (translate.php)
New dedicated tool for translating Norwegian legal documents (Barnevernet letters, court decisions, correspondence) into the user's chosen language with legal-terminology annotations. - translate.php: new tool page with source/target language selectors, 4-way UI lang switcher, file upload, doc picker, streaming results - api/translate.php: NDJSON streaming endpoint; Azure GPT-4o-mini with legal-aware prompt that preserves Norwegian statute refs verbatim and annotates terms with no target-language equivalent; 2-credit cost - assets/js/translate.js: form handler, NDJSON stream reader, copy button - assets/css/tools.css: .lt-* styles for translation result + annotations - includes/i18n.php: 22 lt_* keys × 4 languages; translate entry in nav - includes/FreeTier.php: translate → 2 credits - includes/CaseResults.php + case-result.php: translate in eligible tools, toolLabel, toolIcon, deriveTitle, rendering block, rerun map Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -298,6 +298,33 @@ function crField(string $label, string $value): string {
|
||||
<?php endif; ?>
|
||||
<?= crListBlock('What Remains Uncertain', (array)($output['what_remains_uncertain'] ?? [])) ?>
|
||||
|
||||
<?php elseif ($toolSlug === 'translate'): ?>
|
||||
<?php if (!empty($output['translated_text'])): ?>
|
||||
<div class="cr-block">
|
||||
<div style="display:flex;align-items:center;gap:0.75rem;margin-bottom:0.6rem;">
|
||||
<h3 style="margin:0">Translation</h3>
|
||||
<?php if (!empty($output['source_lang']) && !empty($output['target_lang'])): ?>
|
||||
<span style="font-size:0.8rem;font-family:monospace;background:#f1f5f9;border:1px solid #cbd5e1;border-radius:4px;padding:0.2rem 0.5rem;color:#475569;"><?= htmlspecialchars(strtoupper((string)$output['source_lang'])) ?> → <?= htmlspecialchars(strtoupper((string)$output['target_lang'])) ?></span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<pre style="white-space:pre-wrap;font-size:0.93rem;line-height:1.75;border:1px solid #cbd5e1;border-radius:8px;padding:1.1rem 1.4rem;background:#f8fafc;color:#1e293b;max-height:60vh;overflow-y:auto;"><?= htmlspecialchars((string)$output['translated_text']) ?></pre>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php if (!empty($output['annotations']) && is_array($output['annotations'])): ?>
|
||||
<div class="cr-block">
|
||||
<h3>Legal term notes</h3>
|
||||
<?php foreach ($output['annotations'] as $ann): if (!is_array($ann)) continue; ?>
|
||||
<div style="background:#f8fafc;border-left:3px solid #0f766e;padding:0.45rem 0.75rem;margin-bottom:0.45rem;border-radius:0 6px 6px 0;font-size:0.87rem;">
|
||||
<strong style="font-family:monospace;color:#0e7490;"><?= htmlspecialchars((string)($ann['term'] ?? '')) ?></strong>
|
||||
<?php if (!empty($ann['explanation'])): ?> — <?= htmlspecialchars((string)$ann['explanation']) ?><?php endif; ?>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php if (!empty($output['disclaimer'])): ?>
|
||||
<p style="font-size:0.85rem;color:#64748b;margin-top:1rem;"><em><?= htmlspecialchars((string)$output['disclaimer']) ?></em></p>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php elseif ($toolSlug === 'legal-analysis'): ?>
|
||||
<?php if (!empty($output['overall_assessment'])): ?>
|
||||
<div class="cr-block">
|
||||
@@ -429,6 +456,7 @@ function crField(string $label, string $value): string {
|
||||
'redact': '/redact.php',
|
||||
'transcribe': '/transcribe.php',
|
||||
'legal-analysis':'/legal-analysis.php',
|
||||
'translate': '/translate.php',
|
||||
}[tool] || '/dashboard.php';
|
||||
window.location.href = path + '?rerun=' + <?= (int)$result['id'] ?>;
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user