`;
elements.roomContainer.appendChild(roomDiv);
});
}
function renderItemsInRoom(roomId, items) {
const container = document.getElementById(`items-for-room-${roomId}`);
if (!container) return;
const roomData = allPalaceData.rooms.find(r => r.id === roomId);
if (roomData) roomData.items = items;
if (items.length === 0) {
container.innerHTML = `
`).join('');
}
function openModal(modal) {
modal.classList.remove('hidden');
setTimeout(() => {
modal.querySelector('.modal-overlay')?.classList.remove('opacity-0');
modal.querySelector('.modal-container')?.classList.remove('scale-95');
}, 10);
}
function closeModal(modal) {
modal.querySelector('.modal-overlay')?.classList.add('opacity-0');
modal.querySelector('.modal-container')?.classList.add('scale-95');
setTimeout(() => {
modal.classList.add('hidden');
}, 300);
}
async function handleAddRoom(e) {
e.preventDefault();
const roomName = elements.roomNameInput.value.trim();
if (!roomName || !currentPalaceId) return;
try {
const roomsCol = collection(db, 'artifacts', appId, 'public', 'data', 'memory-palaces', currentPalaceId, 'rooms');
await addDoc(roomsCol, { name: roomName, createdAt: serverTimestamp() });
elements.roomForm.reset();
closeModal(elements.roomModal);
} catch (error) {
console.error("Error adding room:", error);
showMessage("Failed to add room.", "error");
}
}
async function handleAddItem(e) {
e.preventDefault();
const roomId = elements.itemRoomIdInput.value;
const location = elements.itemLocationInput.value.trim();
const information = elements.itemToMemorizeInput.value.trim();
if (!roomId || !location || !information) return;
try {
const itemsCol = collection(db, 'artifacts', appId, 'public', 'data', 'memory-palaces', currentPalaceId, 'rooms', roomId, 'items');
await addDoc(itemsCol, { location, information, createdAt: serverTimestamp() });
elements.itemForm.reset();
closeModal(elements.itemModal);
} catch (error) {
console.error("Error adding item:", error);
showMessage("Failed to add item.", "error");
}
}
function downloadPdf() {
if (!allPalaceData.info) {
showMessage("No palace data to export.", "error");
return;
}
const { jsPDF } = window.jspdf;
const doc = new jsPDF();
doc.setFont('helvetica', 'bold');
doc.setFontSize(18);
doc.text(allPalaceData.info.name, doc.internal.pageSize.getWidth() / 2, 20, { align: 'center' });
doc.setFont('helvetica', 'normal');
doc.setFontSize(12);
doc.text(allPalaceData.info.description, doc.internal.pageSize.getWidth() / 2, 28, { align: 'center' });
doc.setFontSize(10);
doc.setTextColor(150);
doc.text(`Palace ID: ${currentPalaceId}`, doc.internal.pageSize.getWidth() / 2, 35, { align: 'center' });
let startY = 45;
allPalaceData.rooms.forEach(room => {
if (startY > 260) {
doc.addPage();
startY = 20;
}
const tableBody = room.items.map(item => [item.location, item.information]);
doc.autoTable({
startY: startY,
head: [[room.name]],
body: [],
theme: 'striped',
headStyles: { fillColor: [79, 70, 229], fontSize: 14 },
});
doc.autoTable({
startY: doc.autoTable.previous.finalY,
head: [['Location in Room', 'Information to Memorize']],
body: tableBody,
theme: 'grid',
});
startY = doc.autoTable.previous.finalY + 15;
});
doc.save(`${allPalaceData.info.name.replace(/\s+/g, '-')}-memory-palace.pdf`);
}
// --- Firebase Initialization and Auth ---
async function initializeFirebase() {
try {
const app = initializeApp(firebaseConfig);
db = getFirestore(app);
auth = getAuth(app);
onAuthStateChanged(auth, (user) => { userId = user ? user.uid : null; });
if (typeof __initial_auth_token !== 'undefined' && __initial_auth_token) {
await signInWithCustomToken(auth, __initial_auth_token);
} else {
await signInAnonymously(auth);
}
} catch (error) {
console.error("Firebase initialization failed:", error);
showMessage("Could not connect to the service.", "error");
}
}
// --- Event Listeners ---
elements.btnCreatePalace.addEventListener('click', createPalace);
elements.btnJoinPalace.addEventListener('click', () => {
const id = elements.joinPalaceIdInput.value.trim();
if (id) loadPalace(id); else showMessage("Please enter a Palace ID.", "error");
});
elements.btnCopyId.addEventListener('click', () => {
navigator.clipboard.writeText(currentPalaceId).then(() => showMessage("Palace ID copied!", "success"));
});
elements.btnDownloadPdf.addEventListener('click', downloadPdf);
elements.btnAddRoomOpen.addEventListener('click', () => openModal(elements.roomModal));
elements.roomForm.addEventListener('submit', handleAddRoom);
elements.itemForm.addEventListener('submit', handleAddItem);
document.body.addEventListener('click', (e) => {
if (e.target.classList.contains('btn-add-item-open')) {
const roomId = e.target.dataset.roomId;
elements.itemRoomIdInput.value = roomId;
openModal(elements.itemModal);
}
if (e.target.classList.contains('btn-modal-close') || e.target.closest('.btn-modal-close')) {
closeModal(e.target.closest('.modal-overlay'));
}
});
// --- Start the app ---
initializeFirebase();
No items in this room yet.
`; return; } container.innerHTML = items.map(item => `${item.location}
${item.information}
