Files
eye/src/App.jsx
almazlar 3b5f5a6036
All checks were successful
Docker Build and Push / build-and-push (push) Successful in 11s
style: change main title heading from h2 to h1
2026-02-09 00:41:36 +03:00

161 lines
4.5 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { useState } from 'react';
import { Camera, RefreshCw, Languages, Loader2 } from 'lucide-react';
import { resizeImage } from './utils/imageUtils';
import { analyzeImage, translateText } from './services/api';
function App() {
const [image, setImage] = useState(null); // { base64, previewUser }
const [status, setStatus] = useState('idle'); // idle, analyzing, success, translating, translated, error
const [description, setDescription] = useState('');
const [translation, setTranslation] = useState('');
const [error, setError] = useState('');
const handleFileChange = async (e) => {
if (e.target.files && e.target.files[0]) {
try {
const file = e.target.files[0];
const resized = await resizeImage(file);
setImage(resized);
setStatus('ready');
setError('');
setDescription('');
setTranslation('');
} catch (err) {
console.error(err);
setError("Görsel işlenirken bir hata oluştu.");
}
}
};
const handleAnalyze = async () => {
if (!image) return;
setStatus('analyzing');
setError('');
try {
const result = await analyzeImage(image.base64);
setDescription(result);
setStatus('success');
} catch (err) {
setError("Analiz sırasında hata oluştu: " + err.message);
setStatus('error');
}
};
const handleTranslate = async () => {
if (!description) return;
setStatus('translating');
try {
const result = await translateText(description);
setTranslation(result);
setStatus('translated');
} catch (err) {
setError("Çeviri sırasında hata oluştu: " + err.message);
// Keep status as success to show description still
setStatus('success');
}
};
const handleReset = () => {
setImage(null);
setStatus('idle');
setDescription('');
setTranslation('');
setError('');
};
return (
<div className="container">
<h1>Bu resimde ne var?</h1>
<div className="upload-section" onClick={() => document.getElementById('fileInput').click()}>
<input
type="file"
id="fileInput"
hidden
accept="image/*"
onChange={handleFileChange}
/>
{image ? (
<p>{image.previewUser ? "Görsel Seçildi" : "Görsel Yükleniyor..."}</p>
) : (
<p style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', gap: '8px' }}>
<Camera className="icon" /> 📷 Görseli seçmek için buraya tıklayın
</p>
)}
</div>
{image && (
<img
src={image.previewUser}
alt="Preview"
className="preview-image"
/>
)}
{error && (
<div style={{ color: '#ff6b6b', marginTop: '10px', textAlign: 'center' }}>
{error}
</div>
)}
<button
onClick={handleAnalyze}
disabled={!image || status === 'analyzing' || status === 'translating' || (status !== 'ready' && status !== 'error')}
style={{ display: (status === 'idle' || status === 'ready' || status === 'analyzing' || status === 'error') ? 'flex' : 'none' }}
>
{status === 'analyzing' ? (
<>
<Loader2 className="loader" /> Düşünüyor...
</>
) : (
"Analiz Et"
)}
</button>
{(status === 'success' || status === 'translating' || status === 'translated') && (
<div className="result-box">
<span className="label">English Description</span>
<div>{description}</div>
{status !== 'translated' && (
<button
className="translate-btn"
onClick={handleTranslate}
disabled={status === 'translating'}
>
{status === 'translating' ? (
<>
<Loader2 className="loader" /> Çevriliyor...
</>
) : (
<>
<Languages className="icon" /> Türkçeye Çevir
</>
)}
</button>
)}
</div>
)}
{(status === 'translated' || translation) && (
<div className="result-box translation">
<span className="label">Türkçe Çeviri</span>
<div>{translation}</div>
</div>
)}
{status !== 'idle' && (
<button className="reset-btn" onClick={handleReset}>
<RefreshCw className="icon" /> Yeni Analiz Başlat
</button>
)}
</div>
);
}
export default App;