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 => (

{ 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'}
);
};
const ProductDetail = ({ product }) => (
{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.features.map((feature, index) => (
- {feature}
))}
)}
{product.benefits && product.benefits.length > 0 && (
Faydalar:
{product.benefits.map((benefit, index) => (
- {benefit}
))}
)}
{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
);
};
if (loading) {
return (
);
}
return (
{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;