Files
dashboard/components/AiSummaryModal.tsx
T
Alberto-Audrix 32a36cceff
CI / lint-and-test (push) Canceled after 0s
first commit
2026-07-28 08:55:05 +07:00

95 lines
3.5 KiB
TypeScript

import React, { useState, useEffect } from 'react';
import { apiClient } from '../services/apiService.ts';
import { CpuIcon } from './icons/Icons.tsx';
interface AiSummaryModalProps {
isOpen: boolean;
onClose: () => void;
dashboardData: string;
}
const AiSummaryModal: React.FC<AiSummaryModalProps> = ({ isOpen, onClose, dashboardData }) => {
const [isLoading, setIsLoading] = useState(false);
const [summary, setSummary] = useState('');
const [error, setError] = useState('');
useEffect(() => {
if (isOpen) {
setIsLoading(true);
setSummary('');
setError('');
const systemPrompt =
'Anda adalah analis peternakan ayam broiler CP 707. Buat ringkasan singkat dan profesional dalam Bahasa Indonesia berdasarkan data berikut. Gunakan standar buku Manajemen Broiler CP 707.';
apiClient
.proxyLmStudio(dashboardData, systemPrompt, 0.2)
.then((res) => setSummary(res.response || ''))
.catch((err: Error) => setError(err.message || 'Terjadi kesalahan tidak diketahui.'))
.finally(() => setIsLoading(false));
}
}, [isOpen, dashboardData]);
if (!isOpen) return null;
return (
<div className="fixed inset-0 bg-black bg-opacity-50 flex justify-center items-center z-50 p-4">
<div className="bg-white rounded-xl shadow-2xl w-full max-w-2xl transform transition-all">
<div className="p-6">
<div className="flex justify-between items-center mb-4">
<h2 className="text-2xl font-bold text-gray-800 flex items-center">
<CpuIcon className="mr-3" /> Ringkasan Laporan AI
</h2>
<button onClick={onClose} className="text-gray-400 hover:text-gray-600">
&times;
</button>
</div>
<div className="bg-gray-50 p-4 rounded-lg max-h-[60vh] overflow-y-auto">
{isLoading && (
<div className="flex flex-col items-center justify-center h-48">
<svg
className="animate-spin h-10 w-10 text-red-600"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
>
<circle
className="opacity-25"
cx="12"
cy="12"
r="10"
stroke="currentColor"
strokeWidth="4"
></circle>
<path
className="opacity-75"
fill="currentColor"
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
></path>
</svg>
<p className="mt-4 text-gray-600">AI sedang menganalisis data...</p>
</div>
)}
{error && <p className="text-red-500">{error}</p>}
{summary && (
<div
className="prose prose-sm max-w-none"
dangerouslySetInnerHTML={{ __html: summary.replace(/\n/g, '<br />') }}
/>
)}
</div>
</div>
<div className="bg-gray-100 px-6 py-3 rounded-b-xl text-right">
<button
onClick={onClose}
className="bg-gray-600 text-white px-4 py-2 rounded-lg hover:bg-gray-700 transition duration-300"
>
Tutup
</button>
</div>
</div>
</div>
);
};
export default AiSummaryModal;