import { Button, Card, Badge, Label, Icon, LangBadge } from '../components/primitives' import CodeEditor from '../components/CodeEditor' import ResultGauge from '../components/ResultGauge' import DetailSidebar from '../components/DetailSidebar' import ExplanationPanel from '../components/ExplanationPanel' function buildFeatures(allFeatures) { if (!allFeatures) return [] const styleKeys = ['avg_identifier_length', 'avg_function_name_length', 'single_char_name_ratio', 'naming_consistency', 'comment_ratio', 'num_docstrings', 'lexical_diversity', 'trailing_whitespace_ratio'] const structKeys = ['num_functions', 'avg_function_length', 'max_nesting_depth', 'cyclomatic_complexity_approx', 'if_density', 'for_density', 'ast_depth'] const statKeys = ['char_entropy', 'token_entropy', 'perplexity'] const toFeature = (key, category) => { const val = allFeatures[key] if (val === undefined || val === null) return null const fmtVal = typeof val === 'number' ? (key.includes('ratio') || key.includes('density') ? (val * 100).toFixed(1) + '%' : val.toFixed ? val.toFixed(2) : String(val)) : String(val) const severity = key.includes('length') && val > 6 ? 'high' : key === 'naming_consistency' && val > 0.7 ? 'high' : key === 'comment_ratio' && val > 0.2 ? 'high' : key.includes('entropy') ? 'medium' : 'low' return { name: key.replace(/_/g, ' '), value: fmtVal, severity, category } } return [ ...styleKeys.map(k => toFeature(k, 'Style')), ...structKeys.map(k => toFeature(k, 'Structure')), ...statKeys.map(k => toFeature(k, 'Statistical')), ].filter(Boolean) } // Anotacije sada dolaze direktno s backenda (analyze_lines funkcija) // Backend analizira svaku liniju i detektira konkretne AI signale: // "red" = jak signal (docstringovi, dugački identifikatori) // "amber" = umjeren signal (komentari, type anotacije, exception handling) function buildAnnotations(row) { if (row?.line_annotations?.length) { return row.line_annotations } // Fallback: ako nema backendskih anotacija (stariji model), vraćamo prazno return [] } export default function DetailScreen({ row, onBack }) { if (!row) return null const prob = Math.round((row.ai_probability || 0) * 100) const tone = prob >= 70 ? 'red' : prob >= 40 ? 'amber' : 'green' const label = prob >= 70 ? 'LIKELY AI' : prob >= 40 ? 'POSSIBLY AI' : 'LIKELY HUMAN' const lang = row.detected_language || 'python' const langDisplay = lang.charAt(0).toUpperCase() + lang.slice(1) const features = buildFeatures(row.all_features) const annotations = buildAnnotations(row) const code = row.code || '// Code not available' return (
{/* Header */}
{row.id} {label}
{row.file || row.id}
{annotations.length > 0 && ( {annotations.length} suspicious lines flagged )}
) }