'use client'; import { useState, useEffect, useRef } from 'react'; import { Button } from '@/components/ui/button'; import { Textarea } from '@/components/ui/textarea'; import { Card, CardContent, CardDescription, CardHeader, CardTitle, CardFooter } from '@/components/ui/card'; import { Loader2, Upload, FileDown, Download } from 'lucide-react'; import { sentimentApi } from '@/services/api'; import { readTextsFromFile, downloadResultsAsExcel, downloadTemplateExcel } from '@/utils/excelUtils'; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'; export function PlaygroundSection() { const [textInput, setTextInput] = useState(''); const [isLoading, setIsLoading] = useState(false); const [results, setResults] = useState([]); // Mapping Sentimen dinamis dari backend const [sentimentMap, setSentimentMap] = useState>({}); const fileInputRef = useRef(null); const fetchInfo = async () => { try { const info = await sentimentApi.getInfo(); const labelSize = info.data?.label_size || {}; // Ekstrak keys dan konversi ke integer const keys = Object.keys(labelSize).map(Number).sort((a, b) => a - b); if (keys.length > 0) { const minKey = keys[0]; const maxKey = keys[keys.length - 1]; const newMap: Record = {}; keys.forEach(k => { if (k === minKey) newMap[k] = 'Negatif'; else if (k === maxKey) newMap[k] = 'Positif'; else newMap[k] = 'Netral'; }); setSentimentMap(newMap); return newMap; } } catch (error) { console.error('Gagal mengambil info model:', error); } return null; }; useEffect(() => { fetchInfo(); }, []); const getSentimentLabel = (value: number, currentMap: Record) => { if (value === undefined || value === null) return 'Tidak Diketahui'; // Gunakan mapping dari backend jika ada if (currentMap && currentMap[String(value)]) { return currentMap[String(value)]; } // Fallback default jika mapping backend belum/gagal dimuat if (value === 0) return 'Negatif'; if (value === 1 || value === 2) return 'Positif'; return 'Tidak Diketahui'; }; const handlePredictSingle = async () => { if (!textInput.trim()) return; setIsLoading(true); try { let activeMap = sentimentMap; if (Object.keys(activeMap).length === 0) { const loadedMap = await fetchInfo(); if (loadedMap) activeMap = loadedMap; } const response = await sentimentApi.predict([textInput]); if (response && response.length > 0) { setResults([ { Teks: textInput, Sentimen: getSentimentLabel(response[0].sentiment, activeMap) } ]); } } catch (error: any) { console.error('Gagal memprediksi:', error); if (error.response?.status === 500 || error.response?.status === 503) { alert('Server Machine Learning sedang bermasalah (Error 500/503). Silakan coba beberapa saat lagi.'); } else { alert('Terjadi kesalahan saat memproses permintaan.'); } } finally { setIsLoading(false); } }; const handleFileUpload = async (e: React.ChangeEvent) => { const file = e.target.files?.[0]; if (!file) return; setIsLoading(true); setResults([]); setTextInput(''); try { const texts = await readTextsFromFile(file); if (texts.length === 0) { alert('File kosong atau tidak valid.'); setIsLoading(false); return; } let activeMap = sentimentMap; if (Object.keys(activeMap).length === 0) { const loadedMap = await fetchInfo(); if (loadedMap) activeMap = loadedMap; } const response = await sentimentApi.predict(texts); const combinedResults = texts.map((text, idx) => ({ Teks: text, Sentimen: getSentimentLabel(response[idx]?.sentiment, activeMap) })); setResults(combinedResults); } catch (error: any) { console.error('Gagal memproses file:', error); if (error.response?.status === 500 || error.response?.status === 503) { alert('Server Machine Learning sedang bermasalah (Error 500/503). Silakan coba beberapa saat lagi.'); } else { alert('Terjadi kesalahan saat memproses file.'); } } finally { setIsLoading(false); // Reset input file if (fileInputRef.current) { fileInputRef.current.value = ''; } } }; const applyRecommendation = (text: string) => { setTextInput(text); }; return (
{/* Header Section */}

Uji Kalimatmu di Sini

Ketik ulasan, keluhan, atau pujian tentang aplikasi belajar Skolla di dalam kotak ini. Model Machine Learning (Naive Bayes) yang kami latih akan langsung menebak apakah kalimatmu bersentimen Positif atau Negatif.

{/* Input Area */} Coba Prediksi Sentimen Masukkan teks secara manual atau import dari file Excel/TXT.