File size: 3,468 Bytes
a0d2afd
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
const dropZone = document.getElementById('drop-zone');
const fileInput = document.getElementById('file-input');
const predictBtn = document.getElementById('predict-btn');
const imageDisplay = document.getElementById('image-display');
const previewSection = document.getElementById('preview-section');
const resultSection = document.getElementById('result-section');
const predictionLabel = document.getElementById('prediction-label');
const confidenceText = document.getElementById('confidence-text');
const confidenceBar = document.getElementById('confidence-bar');
const resetBtn = document.getElementById('reset-btn');

// Trigger file input on click
dropZone.addEventListener('click', () => fileInput.click());

// Drag & Drop Handlers
dropZone.addEventListener('dragover', (e) => {
    e.preventDefault();
    dropZone.classList.add('drag-over');
});

dropZone.addEventListener('dragleave', () => {
    dropZone.classList.remove('drag-over');
});

dropZone.addEventListener('drop', (e) => {
    e.preventDefault();
    dropZone.classList.remove('drag-over');
    if (e.dataTransfer.files.length > 0) {
        handleFile(e.dataTransfer.files[0]);
    }
});

fileInput.addEventListener('change', (e) => {
    if (e.target.files.length > 0) {
        handleFile(e.target.files[0]);
    }
});

function handleFile(file) {
    if (!file.type.startsWith('image/')) {
        alert('Please upload an image file.');
        return;
    }

    const reader = new FileReader();
    reader.onload = (e) => {
        imageDisplay.src = e.target.result;
        dropZone.classList.add('hidden');
        previewSection.classList.remove('hidden');
    };
    reader.readAsDataURL(file);
}

predictBtn.addEventListener('click', async () => {
    predictBtn.disabled = true;
    predictBtn.innerText = 'Analyzing...';

    const formData = new FormData();
    const file = fileInput.files[0] || null; // Simplified, in practice handle drop files too
    
    // For drop-zone files we might need to get them differently, 
    // but for this demo let's assume valid file selection.
    
    // Convert base64 preview back to blob if needed, or just use the file
    formData.append('file', file);

    try {
        const response = await fetch('/predict', {
            method: 'POST',
            body: formData
        });

        const data = await response.json();
        
        if (data.success) {
            showResult(data.class, data.confidence);
        } else {
            alert('Error: ' + data.error);
        }
    } catch (error) {
        console.error('Error:', error);
        alert('Failed to connect to backend.');
    } finally {
        predictBtn.disabled = false;
        predictBtn.innerText = 'Analyze Image';
    }
});

function showResult(className, confidence) {
    previewSection.classList.add('hidden');
    resultSection.style.display = 'block';
    
    predictionLabel.innerText = className.toUpperCase();
    
    const confValue = (confidence * 100).toFixed(1);
    confidenceText.innerText = `${confValue}%`;
    
    // Trigger animation
    setTimeout(() => {
        confidenceBar.style.width = `${confValue}%`;
    }, 100);
}

resetBtn.addEventListener('click', () => {
    resultSection.style.display = 'none';
    dropZone.classList.remove('hidden');
    fileInput.value = '';
    confidenceBar.style.width = '0%';
});