import React, { useState, useEffect } from 'react'; import { initializeApp } from 'firebase/app'; import { getAuth, signInAnonymously, signInWithCustomToken, onAuthStateChanged, signOut } from 'firebase/auth'; // Added signOut import { getFirestore, doc, getDoc, addDoc, setDoc, updateDoc, deleteDoc, onSnapshot, collection, query, where } from 'firebase/firestore'; // Global variables provided by the Canvas environment const appId = typeof __app_id !== 'undefined' ? __app_id : 'default-app-id'; const firebaseConfig = JSON.parse(typeof __firebase_config !== 'undefined' ? __firebase_config : '{}'); const initialAuthToken = typeof __initial_auth_token !== 'undefined' ? __initial_auth_token : null; function App() { const [db, setDb] = useState(null); const [auth, setAuth] = useState(null); const [userId, setUserId] = useState(null); const [products, setProducts] = useState([]); const [currentView, setCurrentView] = useState('list'); // 'list', 'add', 'detail', 'edit', 'login' const [selectedProduct, setSelectedProduct] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [isAdmin, setIsAdmin] = useState(false); // New state for admin status // Initialize Firebase and set up authentication listener useEffect(() => { try { const app = initializeApp(firebaseConfig); const firestoreDb = getFirestore(app); const firebaseAuth = getAuth(app); setDb(firestoreDb); setAuth(firebaseAuth); const unsubscribe = onAuthStateChanged(firebaseAuth, async (user) => { if (user) { setUserId(user.uid); console.log("Authenticated user ID:", user.uid); // In a real app, you'd check user.uid against a list of admin UIDs // or check custom claims from a token. For this demo, we'll manage // admin status via the LoginScreen. } else { console.log("No user signed in. Attempting anonymous sign-in."); try { if (initialAuthToken) { await signInWithCustomToken(firebaseAuth, initialAuthToken); } else { await signInAnonymously(firebaseAuth); } } catch (authError) { console.error("Firebase authentication error:", authError); setError("Kimlik doğrulama hatası: " + authError.message); } } setLoading(false); // Authentication state is ready }); return () => unsubscribe(); // Cleanup auth listener on unmount } catch (initError) { console.error("Firebase initialization error:", initError); setError("Firebase başlatma hatası: " + initError.message); setLoading(false); } }, []); // Fetch products when db and userId are available useEffect(() => { if (db && userId) { const productsCollectionRef = collection(db, `artifacts/${appId}/users/${userId}/products`); const unsubscribe = onSnapshot(productsCollectionRef, (snapshot) => { const productList = snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() })); setProducts(productList); setError(null); // Clear any previous errors }, (err) => { console.error("Firestore snapshot error:", err); setError("Ürünler yüklenirken hata oluştu: " + err.message); } ); return () => unsubscribe(); // Cleanup snapshot listener } }, [db, userId]); const handleAddProduct = async (productData) => { if (!db || !userId) { setError("Veritabanı veya kullanıcı kimliği mevcut değil."); return; } if (!isAdmin) { setError("Ürün eklemek için yetkili olmanız gerekmektedir."); setCurrentView('login'); return; } try { const productsCollectionRef = collection(db, `artifacts/${appId}/users/${userId}/products`); await addDoc(productsCollectionRef, productData); setCurrentView('list'); setError(null); } catch (err) { console.error("Ürün eklenirken hata:", err); setError("Ürün eklenirken hata oluştu: " + err.message); } }; const handleUpdateProduct = async (id, productData) => { if (!db || !userId) { setError("Veritabanı veya kullanıcı kimliği mevcut değil."); return; } if (!isAdmin) { setError("Ürün düzenlemek için yetkili olmanız gerekmektedir."); setCurrentView('login'); return; } try { const productDocRef = doc(db, `artifacts/${appId}/users/${userId}/products`, id); await updateDoc(productDocRef, productData); setCurrentView('list'); setError(null); } catch (err) { console.error("Ürün güncellenirken hata:", err); setError("Ürün güncellenirken hata oluştu: " + err.message); } }; const handleDeleteProduct = async (id) => { if (!db || !userId) { setError("Veritabanı veya kullanıcı kimliği mevcut değil."); return; } if (!isAdmin) { setError("Ürün silmek için yetkili olmanız gerekmektedir."); setCurrentView('login'); return; } // Instead of alert, use a custom modal or confirmation UI if (window.confirm("Bu ürünü silmek istediğinizden emin misiniz?")) { // Using window.confirm for simplicity, replace with custom UI try { const productDocRef = doc(db, `artifacts/${appId}/users/${userId}/products`, id); await deleteDoc(productDocRef); setCurrentView('list'); setError(null); } catch (err) { console.error("Ürün silinirken hata:", err); setError("Ürün silinirken hata oluştu: " + err.message); } } }; const handleAdminLoginSuccess = () => { setIsAdmin(true); setCurrentView('list'); // Redirect to list after successful login setError(null); }; const handleLogout = async () => { setIsAdmin(false); // Optional: Sign out from Firebase if you want to clear the anonymous session too // try { // if (auth) { // await signOut(auth); // } // } catch (err) { // console.error("Logout error:", err); // } setCurrentView('list'); }; const ProductList = () => (

Ürün Listesi

{isAdmin ? (
) : ( )} {userId && (
Kullanıcı Kimliği: {userId}
)}
{products.length === 0 ? (

Henüz hiç ürün eklenmedi. İlk ürününüzü eklemek için {isAdmin ? 'yukarıdaki düğmeyi' : 'yönetici olarak giriş yapın'}!

) : (
{products.map(product => (
{product.name { e.target.onerror = null; e.target.src = `https://placehold.co/400x300/E0E0E0/333333?text=${encodeURIComponent(product.name || 'Ürün Resmi')}`; }} />

{product.name}

{product.description}

{isAdmin && ( )}
))}
)}
); const ProductForm = ({ onSubmit, initialData = {} }) => { const [name, setName] = useState(initialData.name || ''); const [description, setDescription] = useState(initialData.description || ''); const [features, setFeatures] = useState(initialData.features ? initialData.features.join('\n') : ''); const [benefits, setBenefits] = useState(initialData.benefits ? initialData.benefits.join('\n') : ''); const [usage, setUsage] = useState(initialData.usage || ''); const [imageUrl, setImageUrl] = useState(initialData.imageUrl || ''); const [isGenerating, setIsGenerating] = useState(false); // State for AI generation loading const [aiError, setAiError] = useState(null); // State for AI generation errors const handleSubmit = (e) => { e.preventDefault(); const productData = { name, description, features: features.split('\n').filter(f => f.trim() !== ''), benefits: benefits.split('\n').filter(b => b.trim() !== ''), usage, imageUrl, createdAt: initialData.createdAt || new Date().toISOString(), updatedAt: new Date().toISOString(), }; onSubmit(productData); }; const handleGenerateWithAI = async () => { if (!name.trim()) { setAiError("Lütfen önce ürün adını girin."); return; } setIsGenerating(true); setAiError(null); try { const prompt = `"${name}" adlı ürün için kısa bir açıklama, özellikler (maddeler halinde), faydalar (maddeler halinde) ve kullanım şekli (detaylı) oluştur. Cevabı aşağıdaki JSON formatında döndür:\n\n` + `{\n "description": "...",\n "features": ["...", "..."],\n "benefits": ["...", "..."],\n "usage": "..."\n}`; let chatHistory = []; chatHistory.push({ role: "user", parts: [{ text: prompt }] }); const payload = { contents: chatHistory, generationConfig: { responseMimeType: "application/json", responseSchema: { type: "OBJECT", properties: { "description": { "type": "STRING" }, "features": { "type": "ARRAY", "items": { "type": "STRING" } }, "benefits": { "type": "ARRAY", "items": { "type": "STRING" } }, "usage": { "type": "STRING" } }, "required": ["description", "features", "benefits", "usage"] } } }; const apiKey = ""; // Canvas will provide this at runtime const apiUrl = `https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=${apiKey}`; const response = await fetch(apiUrl, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload) }); const result = await response.json(); if (result.candidates && result.candidates.length > 0 && result.candidates[0].content && result.candidates[0].content.parts && result.candidates[0].content.parts.length > 0) { const jsonString = result.candidates[0].content.parts[0].text; const parsedJson = JSON.parse(jsonString); setDescription(parsedJson.description || ''); setFeatures(parsedJson.features ? parsedJson.features.join('\n') : ''); setBenefits(parsedJson.benefits ? parsedJson.benefits.join('\n') : ''); setUsage(parsedJson.usage || ''); } else { setAiError("AI'dan beklenen yanıt alınamadı."); console.error("AI yanıt yapısı beklenenden farklı:", result); } } catch (err) { console.error("AI ile doldurma hatası:", err); setAiError("AI ile doldurma sırasında bir hata oluştu: " + err.message); } finally { setIsGenerating(false); } }; return (

{initialData.id ? 'Ürünü Düzenle' : 'Yeni Ürün Ekle'}

setName(e.target.value)} className="shadow appearance-none border rounded-lg w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:ring-2 focus:ring-blue-500" required />
{aiError && (
AI Hatası! {aiError}
)}
setImageUrl(e.target.value)} className="shadow appearance-none border rounded-lg w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:ring-2 focus:ring-blue-500" />
); }; const ProductDetail = ({ product }) => (

{product.name}

{product.name { e.target.onerror = null; e.target.src = `https://placehold.co/600x400/E0E0E0/333333?text=${encodeURIComponent(product.name || 'Ürün Resmi')}`; }} />

{product.description}

{product.features && product.features.length > 0 && (

Özellikler:

)} {product.benefits && product.benefits.length > 0 && (

Faydalar:

)} {product.usage && (

Kullanım Şekli:

{product.usage}

)}
{isAdmin && ( <> )}
); // New LoginScreen component const LoginScreen = ({ onLoginSuccess }) => { const [password, setPassword] = useState(''); const [loginError, setLoginError] = useState(null); const handleLogin = (e) => { e.preventDefault(); // This is a placeholder for a real authentication check. // In a real app, you'd use Firebase Auth (email/password, etc.) // For demo purposes, a simple hardcoded password. if (password === 'admin123') { // DEMO PASSWORD onLoginSuccess(); setLoginError(null); } else { setLoginError("Yanlış şifre. Lütfen tekrar deneyin."); } }; return (

Yönetici Girişi

setPassword(e.target.value)} className="shadow appearance-none border rounded-lg w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:ring-2 focus:ring-blue-500" required />
{loginError && (
{loginError}
)}
); }; if (loading) { return (
Yükleniyor...
); } return (

Ürün Tanıtım Portalı

Ürünlerinizin özelliklerini, faydalarını ve kullanım şekillerini keşfedin.

{error && (
Hata! {error}
)} {currentView === 'list' && } {currentView === 'add' && isAdmin && } {currentView === 'edit' && isAdmin && selectedProduct && ( handleUpdateProduct(selectedProduct.id, data)} initialData={selectedProduct} /> )} {currentView === 'detail' && } {currentView === 'login' && } {/* If trying to access admin-only views without being admin, redirect to login */} {(currentView === 'add' || currentView === 'edit') && !isAdmin && currentView !== 'login' && (
Bu sayfaya erişmek için yönetici olarak giriş yapmalısınız.
)}
); } export default App;