import React, { useState, useRef } from 'react'; import { ScissorsIcon, SparklesIcon, UploadCloudIcon, DownloadIcon, AlertTriangleIcon } from '../components/icons'; import Spinner from '../components/Spinner'; import { AppStatus } from '../types'; import { editBonsaiWithKontext } from '../services/mcpService'; import { isAIConfigured } from '../services/geminiService'; // Though this view doesn't use Gemini, we can check for consistency import type { View } from '../types'; const VirtualTrimmerView: React.FC<{ setActiveView: (view: View) => void }> = ({ setActiveView }) => { const [status, setStatus] = useState(AppStatus.IDLE); const [image, setImage] = useState<{ preview: string; base64: string } | null>(null); const [editedImage, setEditedImage] = useState(null); const [prompt, setPrompt] = useState(''); const [error, setError] = useState(''); const fileInputRef = useRef(null); const aiConfigured = isAIConfigured(); // We check this mainly to keep the UI consistent const handleFileChange = (event: React.ChangeEvent) => { const file = event.target.files?.[0]; if (file) { if (file.size > 4 * 1024 * 1024) { // 4MB limit setError("File size exceeds 4MB. Please upload a smaller image."); return; } const reader = new FileReader(); reader.onloadend = () => { const base64String = (reader.result as string).split(',')[1]; setImage({ preview: reader.result as string, base64: base64String }); setEditedImage(null); setError(''); setStatus(AppStatus.IDLE); }; reader.onerror = () => setError("Failed to read the file."); reader.readAsDataURL(file); } }; const handleGenerate = async () => { if (!image) { setError("Please upload an image first."); return; } if (!prompt.trim()) { setError("Please enter an editing instruction."); return; } setStatus(AppStatus.ANALYZING); setError(''); setEditedImage(null); const result = await editBonsaiWithKontext(image.base64, prompt); if (result) { setEditedImage(result); setStatus(AppStatus.SUCCESS); } else { setError('Failed to generate edit. The AI model may be busy or the request could not be completed. Please try again.'); setStatus(AppStatus.ERROR); } }; const presetPrompts = [ "Trim the lowest branch on the left.", "Remove all dead leaves.", "Make the apex more rounded.", "Slightly shorten the longest branch on the right.", "Make the foliage pads more dense and defined.", "Remove the small branch growing towards the viewer.", ]; return (

Virtual Trimmer

Visualize changes to your bonsai before you make a single cut. Describe your edit and let the AI show you the result.

{/* Controls */}
fileInputRef.current?.click()} className="mt-1 flex justify-center p-4 rounded-lg border-2 border-dashed border-stone-300 hover:border-green-600 transition-colors cursor-pointer">
{image ?

Image Loaded!

: }

{image ? 'Click to change image' : 'Click to upload'}