import React, { useState, useEffect } from 'react'; // Import the functions you need from the SDKs you need import { initializeApp } from "firebase/app"; import { getAnalytics } from "firebase/analytics"; import { getFirestore, collection, onSnapshot, addDoc, doc, updateDoc, deleteDoc, setLogLevel } from 'firebase/firestore'; import { getAuth, signInAnonymously, onAuthStateChanged } from "firebase/auth"; // --- Helper Components --- // Icon for a trash can, used for the delete button const TrashIcon = () => ( ); // --- Main Application --- export default function App() { // --- State Management --- const [dvds, setDvds] = useState([]); // Holds the list of all DVDs const [newDvdTitle, setNewDvdTitle] = useState(''); // Controlled input for the new DVD title const [isLoading, setIsLoading] = useState(true); // Loading state for initial data fetch const [error, setError] = useState(null); // To store any error messages // State for the checkout modal const [isModalOpen, setIsModalOpen] = useState(false); const [currentDvd, setCurrentDvd] = useState(null); // The DVD being checked out const [borrowerName, setBorrowerName] = useState(''); const [roomNumber, setRoomNumber] = useState(''); // Firebase state const [db, setDb] = useState(null); const [dvdCollection, setDvdCollection] = useState(null); const [auth, setAuth] = useState(null); const [userId, setUserId] = useState(null); // --- Firebase Initialization --- useEffect(() => { try { // Your web app's Firebase configuration const firebaseConfig = { apiKey: "AIzaSyCOrodCVr5c3LpImHqjNhpOKjOBERKybZU", authDomain: "dvd-inventory.firebaseapp.com", projectId: "dvd-inventory", storageBucket: "dvd-inventory.appspot.com", messagingSenderId: "504734295247", appId: "1:504734295247:web:afe9032b97d0f98a4443ba", measurementId: "G-466YGTV3DD" }; // Initialize Firebase const app = initializeApp(firebaseConfig); const analytics = getAnalytics(app); const firestore = getFirestore(app); const authInstance = getAuth(app); setDb(firestore); setAuth(authInstance); setLogLevel('debug'); // Optional: for detailed logs // Use the project ID for the collection path to keep it unique const dvdsCollectionRef = collection(firestore, `artifacts/dvd-inventory/public/data/dvds`); setDvdCollection(dvdsCollectionRef); } catch (e) { console.error("Firebase initialization failed:", e); setError("Could not connect to the database. Please check the configuration."); setIsLoading(false); } }, []); // --- Authentication --- useEffect(() => { if (!auth) return; // Sign in the user anonymously. This creates a unique session for every user. signInAnonymously(auth).catch(error => { console.error("Anonymous authentication failed:", error); setError("Authentication failed. Some features might not work."); }); const unsubscribe = onAuthStateChanged(auth, (user) => { if (user) { setUserId(user.uid); } else { setUserId(null); } }); return () => unsubscribe(); }, [auth]); // --- Data Fetching (Real-time) --- useEffect(() => { // Only try to fetch data if the collection reference is set and user is authenticated if (!dvdCollection || !userId) { setIsLoading(!userId); // If no user, we are still in a loading/auth state return; } setIsLoading(true); // onSnapshot listens for real-time updates to the collection const unsubscribe = onSnapshot(dvdCollection, (snapshot) => { const dvdsData = snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() })); setDvds(dvdsData); setIsLoading(false); }, (err) => { console.error("Error fetching DVDs:", err); setError("Failed to fetch DVD inventory. Check Firestore rules."); setIsLoading(false); }); // Cleanup function to unsubscribe from the listener when the component unmounts return () => unsubscribe(); }, [dvdCollection, userId]); // --- Core Functions --- /** * Adds a new DVD to the Firestore collection. */ const handleAddDvd = async (e) => { e.preventDefault(); if (!newDvdTitle.trim() || !dvdCollection) return; try { await addDoc(dvdCollection, { title: newDvdTitle.trim(), isAvailable: true, checkedOutBy: null, roomNumber: null, checkoutDate: null, }); setNewDvdTitle(''); // Clear input field on success } catch (err) { console.error("Error adding DVD:", err); setError("Failed to add new DVD."); } }; /** * Deletes a DVD from the Firestore collection. */ const handleDeleteDvd = async (dvdId) => { if (!db) return; try { const dvdDocRef = doc(db, dvdCollection.path, dvdId); await deleteDoc(dvdDocRef); } catch (err) { console.error("Error deleting DVD:", err); setError("Failed to delete DVD."); } }; /** * Opens the checkout modal and sets the current DVD. */ const openCheckoutModal = (dvd) => { setCurrentDvd(dvd); setBorrowerName(''); setRoomNumber(''); setIsModalOpen(true); }; /** * Handles the submission of the checkout form. */ const handleCheckoutSubmit = async (e) => { e.preventDefault(); if (!borrowerName.trim() || !roomNumber.trim() || !currentDvd || !db) return; const today = new Date().toLocaleDateString(); const dvdDocRef = doc(db, dvdCollection.path, currentDvd.id); try { await updateDoc(dvdDocRef, { isAvailable: false, checkedOutBy: borrowerName.trim(), roomNumber: roomNumber.trim(), checkoutDate: today, }); setIsModalOpen(false); // Close modal on success } catch (err) { console.error("Error checking out DVD:", err); setError("Failed to check out DVD."); } }; /** * Checks in a DVD, making it available again. */ const handleCheckIn = async (dvdId) => { if (!db) return; const dvdDocRef = doc(db, dvdCollection.path, dvdId); try { await updateDoc(dvdDocRef, { isAvailable: true, checkedOutBy: null, roomNumber: null, checkoutDate: null, }); } catch (err) { console.error("Error checking in DVD:", err); setError("Failed to check in DVD."); } }; // --- Render UI --- return (
Manage your DVD collection with ease.
{userId &&Session ID: {userId}
}Loading inventory...
) : dvds.length === 0 && !error ? (Use the form above to add your first DVD.
Checked Out
To: {dvd.checkedOutBy}
Room: {dvd.roomNumber}
Date: {dvd.checkoutDate}
"{currentDvd?.title}"