This commit is contained in:
Aherobo Ovie Victor
2025-07-21 19:20:44 +01:00
parent 0b7af4050e
commit 7908b94d40
124 changed files with 968 additions and 3499 deletions
+159
View File
@@ -0,0 +1,159 @@
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
line-height: 1.6;
background-color: #f5f5f5;
color: #333;
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: 2rem;
}
h1 {
text-align: center;
margin-bottom: 2rem;
color: #2c3e50;
}
.upload-section {
display: flex;
flex-direction: column;
align-items: center;
gap: 1rem;
margin-bottom: 2rem;
}
.upload-box {
width: 100%;
max-width: 500px;
height: 200px;
border: 2px dashed #3498db;
border-radius: 8px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
transition: border-color 0.3s ease;
background-color: #fff;
}
.upload-box:hover {
border-color: #2980b9;
}
.upload-content {
text-align: center;
}
.upload-icon {
width: 64px;
height: 64px;
margin-bottom: 1rem;
}
.browse-text {
color: #3498db;
text-decoration: underline;
cursor: pointer;
}
button {
padding: 0.8rem 1.5rem;
font-size: 1rem;
border: none;
border-radius: 4px;
cursor: pointer;
transition: background-color 0.3s ease;
}
#detectButton {
background-color: #3498db;
color: white;
}
#detectButton:disabled {
background-color: #bdc3c7;
cursor: not-allowed;
}
#testButton {
background-color: #2ecc71;
color: white;
}
#detectButton:hover:not(:disabled) {
background-color: #2980b9;
}
#testButton:hover {
background-color: #27ae60;
}
.results-section {
margin-top: 2rem;
}
.image-container {
display: flex;
gap: 2rem;
justify-content: center;
flex-wrap: wrap;
}
.image-box {
flex: 1;
min-width: 300px;
max-width: 500px;
background-color: white;
padding: 1rem;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
.image-box h3 {
margin-bottom: 1rem;
text-align: center;
}
.image-box img {
width: 100%;
height: auto;
border-radius: 4px;
display: none;
}
.loading-spinner {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(255,255,255,0.8);
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
z-index: 1000;
}
.spinner {
width: 50px;
height: 50px;
border: 5px solid #f3f3f3;
border-top: 5px solid #3498db;
border-radius: 50%;
animation: spin 1s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 MiB

+5
View File
@@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 24 24" fill="none" stroke="#3498db" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/>
<polyline points="17 8 12 3 7 8"/>
<line x1="12" y1="3" x2="12" y2="15"/>
</svg>

After

Width:  |  Height:  |  Size: 323 B

+100
View File
@@ -0,0 +1,100 @@
document.addEventListener('DOMContentLoaded', function() {
const dropZone = document.getElementById('dropZone');
const fileInput = document.getElementById('fileInput');
const detectButton = document.getElementById('detectButton');
const testButton = document.getElementById('testButton');
const originalImage = document.getElementById('originalImage');
const resultImage = document.getElementById('resultImage');
const loading = document.getElementById('loading');
// Handle drag and drop
dropZone.addEventListener('dragover', (e) => {
e.preventDefault();
dropZone.style.borderColor = '#2980b9';
});
dropZone.addEventListener('dragleave', (e) => {
e.preventDefault();
dropZone.style.borderColor = '#3498db';
});
dropZone.addEventListener('drop', (e) => {
e.preventDefault();
dropZone.style.borderColor = '#3498db';
const file = e.dataTransfer.files[0];
if (file && file.type.startsWith('image/')) {
handleImageSelection(file);
}
});
// Handle click to upload
dropZone.addEventListener('click', () => {
fileInput.click();
});
fileInput.addEventListener('change', (e) => {
const file = e.target.files[0];
if (file) {
handleImageSelection(file);
}
});
function handleImageSelection(file) {
const reader = new FileReader();
reader.onload = function(e) {
originalImage.src = e.target.result;
originalImage.style.display = 'block';
detectButton.disabled = false;
};
reader.readAsDataURL(file);
}
// Handle detect button click
detectButton.addEventListener('click', async () => {
const formData = new FormData();
formData.append('image', fileInput.files[0]);
try {
loading.style.display = 'flex';
const response = await fetch('/detect', {
method: 'POST',
body: formData
});
if (response.ok) {
const blob = await response.blob();
resultImage.src = URL.createObjectURL(blob);
resultImage.style.display = 'block';
} else {
alert('Error processing image');
}
} catch (error) {
console.error('Error:', error);
alert('Error processing image');
} finally {
loading.style.display = 'none';
}
});
// Handle test button click
testButton.addEventListener('click', async () => {
try {
loading.style.display = 'flex';
const response = await fetch('/detect/test');
if (response.ok) {
const blob = await response.blob();
resultImage.src = URL.createObjectURL(blob);
resultImage.style.display = 'block';
} else {
alert('Error running test detection');
}
} catch (error) {
console.error('Error:', error);
alert('Error running test detection');
} finally {
loading.style.display = 'none';
}
});
});