২00টি SAT গণিত প্রশ্ন যোগ করার জন্য আমি একটি নতুন ফিচার তৈরি করেছি।


import React, { useState, useEffect, useRef } from 'react'; import { initializeApp } from 'firebase/app'; import { getAuth, signInAnonymously, onAuthStateChanged, signInWithCustomToken } from 'firebase/auth'; import { getFirestore, doc, getDoc, setDoc, onSnapshot, collection, query, getDocs } from 'firebase/firestore'; const App = () => { const [currentUser, setCurrentUser] = useState(null); const [balance, setBalance] = useState(0); const [isAuthReady, setIsAuthReady] = useState(false); const [db, setDb] = useState(null); const [auth, setAuth] = useState(null); const [showModal, setShowModal] = useState(false); const [modalMessage, setModalMessage] = useState(''); const [userId, setUserId] = useState(null); const [isAdminLoggedIn, setIsAdminLoggedIn] = useState(false); const [adminPassword, setAdminPassword] = useState(''); const [usersData, setUsersData] = useState([]); const [adminModal, setAdminModal] = useState({ show: false, message: '' }); // কুইজের জন্য নতুন স্টেট const [quizActive, setQuizActive] = useState(false); const [currentQuestionIndex, setCurrentQuestionIndex] = useState(0); const [score, setScore] = useState(0); const [showQuizResult, setShowQuizResult] = useState(false); const adTimers = useRef({}); // প্রতিটি বিজ্ঞাপনের জন্য টাইমার ট্র্যাক করার জন্য // SAT গণিতের ডেমো প্রশ্ন const satQuestions = [ { question: "যদি একটি বৃত্তের ব্যাসার্ধ r হয়, তাহলে এর ক্ষেত্রফল কত?", options: ["2πr", "πr", "πr²", "2πr²"], correctAnswerIndex: 2, }, { question: "যদি x + 3 = 10 হয়, তাহলে x এর মান কত?", options: ["5", "7", "10", "13"], correctAnswerIndex: 1, }, { question: "একটি ত্রিভুজের তিনটি কোণের সমষ্টি কত?", options: ["90°", "180°", "270°", "360°"], correctAnswerIndex: 1, }, // এখানে আরও ১৯৭টি প্রশ্ন যোগ করা যাবে ]; // Firebase কনফিগারেশন এবং ইনিশিয়ালাইজেশন useEffect(() => { try { const firebaseConfig = JSON.parse(typeof __firebase_config !== 'undefined' ? __firebase_config : '{}'); const app = initializeApp(firebaseConfig); const firestore = getFirestore(app); const authentication = getAuth(app); setDb(firestore); setAuth(authentication); const handleAuthState = async () => { if (typeof __initial_auth_token !== 'undefined' && __initial_auth_token) { try { await signInWithCustomToken(authentication, __initial_auth_token); } catch (error) { console.error('Error signing in with custom token:', error); } } else { try { await signInAnonymously(authentication); } catch (error) { console.error('Error signing in anonymously:', error); } } setIsAuthReady(true); }; onAuthStateChanged(authentication, (user) => { if (user) { setCurrentUser(user.uid); setUserId(user.uid); } else { setCurrentUser(null); setUserId(null); } }); handleAuthState(); } catch (error) { console.error("Firebase initialization failed:", error); } }, []); // Firestore থেকে ব্যালেন্স ডেটা লোড করা useEffect(() => { if (db && userId) { const userDocRef = doc(db, 'artifacts', typeof __app_id !== 'undefined' ? __app_id : 'default-app-id', 'users', userId); const unsubscribe = onSnapshot(userDocRef, (docSnap) => { if (docSnap.exists()) { const userData = docSnap.data(); setBalance(userData.balance || 0); } else { // যদি কোনো ডেটা না থাকে, নতুন ডকুমেন্ট তৈরি করা setDoc(userDocRef, { balance: 0, lastSeen: new Date() }).catch(e => console.error("Error setting initial doc:", e)); setBalance(0); } }, (error) => { console.error("Error listening to user data:", error); }); return () => unsubscribe(); } }, [db, userId]); const posts = [ { type: 'post', user: 'রানা আহমেদ', content: 'আজকের আবহাওয়াটা খুব ভালো! সবাই কেমন আছেন?' }, { type: 'ad', adId: 'ad-1', content: 'দারুণ অফার! নতুন ইলেকট্রনিক্স পণ্যে ৫০% ছাড়। সীমিত সময়ের জন্য!', image: 'https://placehold.co/600x400/2980b9/ffffff?text=বিজ্ঞাপন ১' }, { type: 'post', user: 'মারিয়া খান', content: 'এই বইটি পড়ছি, খুবই ভালো লাগছে। আপনাদের প্রিয় বই কোনটি?' }, { type: 'ad-iframe', adId: 'ad-2', iframeSrc: 'https://www.profitableratecpm.com/w6dd1s2ef0?key=6673c8b5db779ea69db9c3483cdf9528' }, { type: 'post', user: 'জাহিদ হাসান', content: 'বন্ধুদের সাথে ঘুরতে যাচ্ছি। দারুণ সময় কাটছে!' }, { type: 'ad', adId: 'ad-3', content: 'স্বাস্থ্যের যত্ন নিন! আমাদের নতুন পণ্য কিনুন এবং সুস্থ থাকুন।', image: 'https://placehold.co/600x400/f39c12/ffffff?text=বিজ্ঞাপন ৩' }, { type: 'post', user: 'ফারহানা ইসলাম', content: 'নতুন একটা রেসিপি চেষ্টা করলাম, সবাই খুব পছন্দ করেছে।' }, { type: 'ad', adId: 'ad-4', content: 'ট্রাভেল প্যাকেজ! কক্সবাজার ট্যুরে ৫০% ছাড়। এখনি বুক করুন।', image: 'https://placehold.co/600x400/8e44ad/ffffff?text=বিজ্ঞাপন ৪' }, ]; // বিজ্ঞাপন দেখার জন্য ইন্টারসেকশন অবজারভার useEffect(() => { if (!isAuthReady || !db || !userId || isAdminLoggedIn || quizActive) return; const observer = new IntersectionObserver((entries) => { entries.forEach(entry => { const adElement = entry.target; const adId = adElement.dataset.adId; if (entry.isIntersecting) { if (!adTimers.current[adId]) { const progressBar = adElement.querySelector('.ad-progress-bar'); let timeElapsed = 0; const duration = 5000; const interval = 50; if (progressBar) { progressBar.style.width = '0'; } adTimers.current[adId] = setInterval(() => { timeElapsed += interval; const progress = (timeElapsed / duration) * 100; if (progressBar) { progressBar.style.width = `${progress}%`; } if (timeElapsed >= duration) { clearInterval(adTimers.current[adId]); delete adTimers.current[adId]; updateBalance(0.10); if (progressBar) { progressBar.style.backgroundColor = '#2ecc71'; } setModalMessage(`অভিনন্দন, আপনি বিজ্ঞাপন দেখে ৳0.10 আয় করেছেন!`); setShowModal(true); } }, interval); } } else { if (adTimers.current[adId]) { clearInterval(adTimers.current[adId]); delete adTimers.current[adId]; const progressBar = adElement.querySelector('.ad-progress-bar'); if (progressBar) { progressBar.style.width = '0'; } } } }); }, { threshold: 0.8 }); document.querySelectorAll('.ad-card').forEach(adCard => { observer.observe(adCard); }); return () => { observer.disconnect(); Object.values(adTimers.current).forEach(clearInterval); }; }, [isAuthReady, db, userId, isAdminLoggedIn, quizActive]); // Firestore-এ ব্যালেন্স আপডেট করার ফাংশন const updateBalance = async (amount) => { if (db && userId) { const userDocRef = doc(db, 'artifacts', typeof __app_id !== 'undefined' ? __app_id : 'default-app-id', 'users', userId); try { const docSnap = await getDoc(userDocRef); const newBalance = (docSnap.exists() ? docSnap.data().balance : 0) + amount; await setDoc(userDocRef, { balance: newBalance }, { merge: true }); } catch (e) { console.error("Error updating balance:", e); } } }; const closeModal = () => { setShowModal(false); setAdminModal({ show: false, message: '' }); }; const handleAdminLogin = () => { // এখানে একটি সাধারণ পাসওয়ার্ড চেক করা হচ্ছে। একটি বাস্তব অ্যাপে, এটি আরও সুরক্ষিত হতে হবে। if (adminPassword === 'admin123') { setIsAdminLoggedIn(true); fetchAllUsers(); } else { setAdminModal({ show: true, message: 'ভুল পাসওয়ার্ড!' }); } }; const handleAdminLogout = () => { setIsAdminLoggedIn(false); setAdminPassword(''); setUsersData([]); }; const fetchAllUsers = async () => { if (db) { const usersCollectionRef = collection(db, 'artifacts', typeof __app_id !== 'undefined' ? __app_id : 'default-app-id', 'users'); const q = query(usersCollectionRef); try { const querySnapshot = await getDocs(q); const allUsers = []; querySnapshot.forEach((doc) => { allUsers.push({ id: doc.id, ...doc.data() }); }); setUsersData(allUsers); } catch (e) { console.error("Error fetching all users:", e); } } }; const handleUpdateUserBalance = async (userId, newBalance) => { if (db) { const userDocRef = doc(db, 'artifacts', typeof __app_id !== 'undefined' ? __app_id : 'default-app-id', 'users', userId); try { await setDoc(userDocRef, { balance: newBalance }, { merge: true }); setAdminModal({ show: true, message: `ব্যবহারকারী ${userId} এর ব্যালেন্স আপডেট করা হয়েছে।` }); fetchAllUsers(); // ডেটা রিফ্রেশ করা } catch (e) { console.error("Error updating user balance:", e); setAdminModal({ show: true, message: 'ব্যালেন্স আপডেট করতে ব্যর্থ হয়েছে।' }); } } }; // কুইজের ফাংশন const handleAnswer = (selectedIndex) => { if (selectedIndex === satQuestions[currentQuestionIndex].correctAnswerIndex) { setScore(score + 1); } const nextQuestion = currentQuestionIndex + 1; if (nextQuestion < satQuestions.length) { setCurrentQuestionIndex(nextQuestion); } else { setShowQuizResult(true); } }; const resetQuiz = () => { setQuizActive(false); setCurrentQuestionIndex(0); setScore(0); setShowQuizResult(false); }; if (!isAuthReady) { return (
অ্যাপ লোড হচ্ছে...
); } // অ্যাডমিন প্যানেল এবং ইউজার ভিউয়ের মধ্যে স্যুইচ করার লজিক const renderApp = () => { if (isAdminLoggedIn) { // অ্যাডমিন প্যানেল UI return (

অ্যাডমিন প্যানেল

ব্যবহারকারীর তালিকা

{usersData.map((user) => ( ))}
ইউজার ID ব্যালেন্স অ্যাকশন
{user.id} ৳{user.balance.toFixed(2)} handleUpdateUserBalance(user.id, parseFloat(e.target.value))} className="w-24 border border-gray-300 rounded-md px-2 py-1 focus:outline-none focus:ring-2 focus:ring-blue-500" />
); } else if (quizActive) { // SAT Math Quiz UI const currentQuestion = satQuestions[currentQuestionIndex]; return (

SAT Math Quiz

{showQuizResult ? (

কুইজ শেষ!

আপনার স্কোর: {score} / {satQuestions.length}

) : (
প্রশ্ন {currentQuestionIndex + 1} / {satQuestions.length}

{currentQuestion.question}

{currentQuestion.options.map((option, index) => ( ))}
)}
); } else { // ইউজার ভিউ UI (হোমপেজ) return (

DaleMi

ইউজার ID: {userId} টাকা: ৳{balance.toFixed(2)}
{posts.map((item, index) => (
{item.type === 'post' ? ( <>
{item.user[0]}
{item.user}

{item.content}

) : item.type === 'ad-iframe' ? (

স্পনসর্ড

) : (

স্পনসর্ড

বিজ্ঞাপন

{item.content}

)}
))}
); } }; return (
{renderApp()} {/* কাস্টম Modal মেসেজ (ইউজারের জন্য) */} {showModal && (

অভিনন্দন!

{modalMessage}

)} {/* অ্যাডমিন লগইন Modal */} {adminModal.show && !isAdminLoggedIn && (

অ্যাডমিন লগইন

পাসওয়ার্ড: admin123

{adminModal.message &&

{adminModal.message}

} setAdminPassword(e.target.value)} className="w-full p-3 border border-gray-300 rounded-md mb-4 focus:outline-none focus:ring-2 focus:ring-blue-500" />
)} {/* অ্যাডমিন মেসেজ Modal */} {adminModal.show && isAdminLoggedIn && (

বিজ্ঞপ্তি

{adminModal.message}

)}
); }; export default App;

No comments: