Generate a structure from the "Define Project" tab first.
';
return;
}
let pathCounter = { count: 0 };
treeContainer.innerHTML = `
${renderNode(folderStructure, '0', pathCounter)}
`;
attachActionListeners();
}
function renderNode(node, path, pathCounter) {
let childrenHtml = '';
if (node.children && node.children.length > 0) {
childrenHtml = `
${node.children.map((child, index) => renderNode(child, `${path}-${index}`, pathCounter)).join('')}
`;
}
pathCounter.count++;
return `
${folderIcon}
${node.name}
${childrenHtml}
`;
}
function getNodeByPath(path) {
const indices = path.split('-').map(Number);
let currentNode = folderStructure;
for (let i = 1; i < indices.length; i++) {
if (!currentNode.children || !currentNode.children[indices[i]]) return null;
currentNode = currentNode.children[indices[i]];
}
return currentNode;
}
function getParentNodeByPath(path) {
if (path === '0') return null; // Root has no parent
const indices = path.split('-').map(Number);
indices.pop(); // Remove last index to get parent path
let parentNode = folderStructure;
for (let i = 1; i < indices.length; i++) {
parentNode = parentNode.children[indices[i]];
}
return parentNode;
}
// --- ACTION HANDLERS ---
function attachActionListeners() {
document.querySelectorAll('.add-btn').forEach(btn => btn.addEventListener('click', handleAdd));
document.querySelectorAll('.edit-btn').forEach(btn => btn.addEventListener('click', handleEdit));
document.querySelectorAll('.delete-btn').forEach(btn => btn.addEventListener('click', handleDelete));
}
function handleAdd(e) {
const path = e.currentTarget.dataset.path;
const parentNode = getNodeByPath(path);
if (!parentNode) return;
const newFolderName = prompt("Enter name for the new subfolder:", "New Folder");
if (newFolderName && newFolderName.trim() !== "") {
if (!parentNode.children) parentNode.children = [];
parentNode.children.push({ name: newFolderName.trim(), children: [] });
renderTree();
}
}
addRootFolderBtn.addEventListener('click', () => {
const newFolderName = prompt("Enter name for the new root folder:", "New Root Folder");
if (newFolderName && newFolderName.trim() !== "") {
if (!folderStructure.children) folderStructure.children = [];
folderStructure.children.push({ name: newFolderName.trim(), children: [] });
renderTree();
}
});
function handleEdit(e) {
const path = e.currentTarget.dataset.path;
const node = getNodeByPath(path);
if (!node) return;
const newName = prompt("Enter new name for the folder:", node.name);
if (newName && newName.trim() !== "") {
node.name = newName.trim();
renderTree();
}
}
function handleDelete(e) {
const path = e.currentTarget.dataset.path;
if (path === '0') {
alert("Cannot delete the main project folder.");
return;
}
const parentNode = getParentNodeByPath(path);
const nodeIndex = parseInt(path.split('-').pop());
if (parentNode && parentNode.children) {
parentNode.children.splice(nodeIndex, 1);
renderTree();
}
}
// --- TAB MANAGEMENT ---
function changeTab(tabIndex) {
if (currentTab === 0 && tabIndex === 1) {
generateStructure();
}
currentTab = tabIndex;
document.querySelectorAll('.tab-pane').forEach((pane, index) => {
pane.classList.toggle('hidden', index !== tabIndex);
});
tabButtons.forEach((button) => {
button.classList.toggle('active', parseInt(button.dataset.tab) === tabIndex);
});
updateNavButtons();
}
function updateNavButtons() {
prevBtn.disabled = currentTab === 0;
prevBtn.classList.toggle('opacity-50', prevBtn.disabled);
nextBtn.disabled = currentTab === TABS_COUNT - 1;
nextBtn.classList.toggle('opacity-50', nextBtn.disabled);
}
tabButtons.forEach(btn => btn.addEventListener('click', () => changeTab(parseInt(btn.dataset.tab))));
prevBtn.addEventListener('click', () => { if (currentTab > 0) changeTab(currentTab - 1) });
nextBtn.addEventListener('click', () => { if (currentTab < TABS_COUNT - 1) changeTab(currentTab + 1) });
// --- PDF DOWNLOAD ---
downloadPdfBtn.addEventListener('click', () => {
const container = document.getElementById('folder-tree-container');
html2canvas(container, { scale: 2, useCORS: true, logging: false }).then(canvas => {
const imgData = canvas.toDataURL('image/png');
const { jsPDF } = window.jspdf;
const doc = new jsPDF({ orientation: 'p', unit: 'mm', format: 'a4' });
const pdfWidth = doc.internal.pageSize.getWidth();
const imgProps = doc.getImageProperties(imgData);
const imgHeight = (imgProps.height * pdfWidth) / imgProps.width;
doc.setFontSize(18);
doc.text(`Folder Structure: ${folderStructure.name}`, pdfWidth / 2, 15, { align: 'center' });
doc.addImage(imgData, 'PNG', 10, 25, pdfWidth - 20, imgHeight - 20);
doc.save('folder-structure.pdf');
});
});
// --- INITIALIZATION ---
changeTab(0);
});