diff --git a/src/App.js b/src/App.js index a9107e6..5827f67 100644 --- a/src/App.js +++ b/src/App.js @@ -214,7 +214,7 @@ function App() { {!isAuthReady && !error &&
Authenticating...
} ); @@ -242,28 +242,48 @@ function ConfirmationModal({ isOpen, onClose, onConfirm, title, message }) { // --- Admin View Component --- function AdminView({ userId }) { - const { data: campaignsData, isLoading: isLoadingCampaigns } = useFirestoreCollection(getCampaignsCollectionPath()); + const { data: campaignsData, isLoading: isLoadingCampaigns, error: campaignsError } = useFirestoreCollection(getCampaignsCollectionPath()); const { data: initialActiveInfoData } = useFirestoreDocument(getActiveDisplayDocPath()); - const [campaigns, setCampaigns] = useState([]); + + const [campaignsWithDetails, setCampaignsWithDetails] = useState([]); const [selectedCampaignId, setSelectedCampaignId] = useState(null); const [showCreateCampaignModal, setShowCreateCampaignModal] = useState(false); const [showDeleteCampaignConfirm, setShowDeleteCampaignConfirm] = useState(false); const [itemToDelete, setItemToDelete] = useState(null); useEffect(() => { - if (campaignsData) { - setCampaigns(campaignsData.map(c => ({ ...c, characters: c.players || [] }))); + if (campaignsData && db) { + const fetchDetails = async () => { + const detailedCampaigns = await Promise.all( + campaignsData.map(async (campaign) => { + const characters = campaign.players || []; + let encounterCount = 0; + try { + const encountersSnapshot = await getDocs(collection(db, getEncountersCollectionPath(campaign.id))); + encounterCount = encountersSnapshot.size; + } catch (err) { + console.error(`Failed to fetch encounters for campaign ${campaign.id} (${campaign.name}):`, err); + } + return { ...campaign, characters, encounterCount }; + }) + ); + setCampaignsWithDetails(detailedCampaigns); + }; + fetchDetails(); + } else if (campaignsData) { + setCampaignsWithDetails(campaignsData.map(c => ({ ...c, characters: c.players || [], encounterCount: 0 }))); } }, [campaignsData]); useEffect(() => { - if (initialActiveInfoData && initialActiveInfoData.activeCampaignId && campaigns.length > 0 && !selectedCampaignId) { - const campaignExists = campaigns.some(c => c.id === initialActiveInfoData.activeCampaignId); + if (initialActiveInfoData && initialActiveInfoData.activeCampaignId && campaignsWithDetails.length > 0 && !selectedCampaignId) { + const campaignExists = campaignsWithDetails.some(c => c.id === initialActiveInfoData.activeCampaignId); if (campaignExists) { setSelectedCampaignId(initialActiveInfoData.activeCampaignId); } } - }, [initialActiveInfoData, campaigns, selectedCampaignId]); + }, [initialActiveInfoData, campaignsWithDetails, selectedCampaignId]); + const handleCreateCampaign = async (name, backgroundUrl) => { if (!db || !name.trim()) return; @@ -297,6 +317,7 @@ function AdminView({ userId }) { await batch.commit(); await deleteDoc(doc(db, getCampaignDocPath(campaignId))); if (selectedCampaignId === campaignId) setSelectedCampaignId(null); + const activeDisplayRef = doc(db, getActiveDisplayDocPath()); const activeDisplaySnap = await getDoc(activeDisplayRef); if (activeDisplaySnap.exists() && activeDisplaySnap.data().activeCampaignId === campaignId) { @@ -307,11 +328,14 @@ function AdminView({ userId }) { setItemToDelete(null); }; - const selectedCampaign = campaigns.find(c => c.id === selectedCampaignId); + const selectedCampaign = campaignsWithDetails.find(c => c.id === selectedCampaignId); if (isLoadingCampaigns) { returnLoading campaigns...
; } + if (campaignsError) { + returnError loading campaigns: {campaignsError.message || String(campaignsError)}
; + } return ( <> @@ -323,15 +347,25 @@ function AdminView({ userId }) {No campaigns yet.
} + {campaignsWithDetails.length === 0 && !isLoadingCampaigns &&No campaigns yet.
}