about summary refs log blame commit diff stats
path: root/html/file-system/index.html
blob: cd2e70dbe1388ef81a0b89baa65cdc08d5954714 (plain) (tree)


































































































































































































































































































                                                                                                                                   
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Files and Folders</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            background-color: beige;
            display: flex;
            flex-direction: column;
            align-items: center;
        }
        #navigation {
            display: flex;
            flex-wrap: wrap;
            justify-content: center;
            margin: 0.625em 0;
        }
        #navigation button {
            margin: 0.3125em;
            padding: 0.625em 0.9375em;
            font-size: 1em;
            flex-grow: 1;
            min-width: 7.5em;
        }
        #currentPath {
            font-weight: bold;
            margin: 0.625em 0;
        }
        ul {
            list-style-type: none;
            width: 100%;
            max-width: 37.5em;
        }
        li {
            margin: 0.3125em 0;
            cursor: pointer;
        }
        .file, .folder {
            display: inline-block;
            padding: 0.3125em 0;
            cursor: pointer;
            font-size: 1.125em;
        }
        .file {
            color: teal;
        }
        .folder {
            color: black;
        }
        #editor {
            margin-top: 1.25em;
            width: 100%;
            max-width: 37.5em;
        }
        #editor textarea {
            width: 100%;
            height: 9.375em;
            font-size: 1em;
            padding: 0.625em;
            box-sizing: border-box;
            resize: none;
        }
        h1 {
            text-align: center;
            font-size: 1.5em;
            margin-top: 0.625em;
        }
        @media (max-width: 37.5em) {
            h1 {
                font-size: 1.25em;
            }
            #navigation button {
                font-size: 0.875em;
                padding: 0.5em 0.625em;
            }
            .file, .folder {
                font-size: 1em;
            }
            #editor textarea {
                height: 7.5em;
                font-size: 0.875em;
            }
        }
    </style>
</head>
<body>

<div id="navigation">
    <button onclick="goToRoot()">Go to Root</button>
    <button onclick="goUp()">Go Up One Level</button>
    <button onclick="createFolderPrompt()">Create Folder</button>
    <button onclick="createFilePrompt()">Create File</button>
    <button onclick="cutItem()">Cut</button>
    <button onclick="pasteItem()">Paste</button>
    <button onclick="deleteItem()">Delete</button>
</div>

<p id="currentPath">Current Folder: /</p>

<ul id="fileSystemTree"></ul>

<div id="editor">
    <h3>File Editor</h3>
    <textarea id="fileContent" placeholder="Select a file to edit"></textarea>
    <button onclick="saveFileContent()">Save</button>
</div>

<script>
    let fileSystem = JSON.parse(localStorage.getItem('fileSystem')) || { root: { type: 'folder', children: {} } };
    let currentFolderPath = 'root';
    let currentFilePath = null;
    let cutItemPath = null;  // For storing the path of the item being cut

    function saveFileSystem() {
        localStorage.setItem('fileSystem', JSON.stringify(fileSystem));
    }

    function getFolder(path) {
        let parts = path.split('/');
        let current = fileSystem.root;
        for (let part of parts) {
            if (part && current.children[part]) {
                current = current.children[part];
            }
        }
        return current;
    }

    function createFile(path, name, content = '') {
        let folder = getFolder(path);
        folder.children[name] = { type: 'file', content };
        saveFileSystem();
        renderFileSystem();
    }

    function createFolder(path, name) {
        let folder = getFolder(path);
        folder.children[name] = { type: 'folder', children: {} };
        saveFileSystem();
        renderFileSystem();
    }

    function moveItem(oldPath, newPath, itemName) {
        let oldFolder = getFolder(oldPath);
        let newFolder = getFolder(newPath);
        newFolder.children[itemName] = oldFolder.children[itemName];
        delete oldFolder.children[itemName];
        saveFileSystem();
        renderFileSystem();
    }

    function deleteItem() {
        if (!currentFilePath && currentFolderPath === 'root') {
            alert("Can't delete the root folder!");
            return;
        }

        let [parentPath, itemName] = (currentFilePath || currentFolderPath).split(/\/([^\/]+)$/);
        let parentFolder = getFolder(parentPath);

        // Check if the item to delete is a folder with children
        if (parentFolder.children[itemName].type === 'folder') {
            let childCount = Object.keys(parentFolder.children[itemName].children).length;
            if (childCount > 0) {
                let confirmDelete = confirm(`Are you sure you want to delete the folder "${itemName}" and all its contents?`);
                if (!confirmDelete) return;
            }
        }

        // Delete the file/folder
        delete parentFolder.children[itemName];
        saveFileSystem();

        // After deletion, reset selection to the parent folder
        currentFilePath = null;
        currentFolderPath = parentPath || 'root';
        document.getElementById('currentPath').textContent = currentFolderPath.replace('root', '') || '/';
        renderFileSystem();
    }

    function editFileContent(path, fileName, newContent) {
        let folder = getFolder(path);
        folder.children[fileName].content = newContent;
        saveFileSystem();
    }

    function saveFileContent() {
        if (currentFilePath) {
            let [path, fileName] = currentFilePath.split(/\/([^\/]+)$/);
            let content = document.getElementById('fileContent').value;
            editFileContent(path, fileName, content);
        }
    }

    // Recursive function to render the file system
    function renderFileSystem(folder = fileSystem.root, parentElement = document.getElementById('fileSystemTree'), path = 'root') {
        parentElement.innerHTML = ''; // Clear existing tree
        for (const [name, item] of Object.entries(folder.children)) {
            let listItem = document.createElement('li');

            // Create a separate clickable span for the folder or file name
            let clickableName = document.createElement('span');
            clickableName.textContent = name;
            clickableName.classList.add(item.type === 'file' ? 'file' : 'folder');
            listItem.appendChild(clickableName);

            // Folder click sets the current folder path
            clickableName.onclick = () => {
                if (item.type === 'folder') {
                    currentFolderPath = `${path}/${name}`;
                    currentFilePath = null;
                    document.getElementById('currentPath').textContent = currentFolderPath.replace('root', '');
                    renderFileSystem();  // Re-render after changing the folder
                } else if (item.type === 'file') {
                    currentFilePath = `${path}/${name}`;
                    document.getElementById('fileContent').value = item.content;
                }
            };

            // If it's a folder, render its children recursively
            if (item.type === 'folder') {
                let nestedList = document.createElement('ul');
                renderFileSystem(item, nestedList, `${path}/${name}`);
                listItem.appendChild(nestedList);
            }

            parentElement.appendChild(listItem);
        }
    }

    // Navigation: Go to root
    function goToRoot() {
        currentFolderPath = 'root';
        currentFilePath = null;
        document.getElementById('currentPath').textContent = '/';
        renderFileSystem();
    }

    // Navigation: Go up one level
    function goUp() {
        if (currentFolderPath !== 'root') {
            let parts = currentFolderPath.split('/');
            parts.pop(); // Remove the current folder
            currentFolderPath = parts.join('/') || 'root';
            currentFilePath = null;
            document.getElementById('currentPath').textContent = currentFolderPath.replace('root', '') || '/';
            renderFileSystem();
        }
    }

    // Cut a file or folder (select it for moving)
    function cutItem() {
        cutItemPath = currentFilePath || currentFolderPath;  // Store the path of the selected file/folder
        alert(`Cut: ${cutItemPath}`);
    }

    // Paste a cut item into the current folder
    function pasteItem() {
        if (!cutItemPath) {
            alert('No item selected to move.');
            return;
        }

        let [oldPath, itemName] = cutItemPath.split(/\/([^\/]+)$/);
        moveItem(oldPath, currentFolderPath, itemName);
        cutItemPath = null;  // Reset the cut item
        alert(`Moved to: ${currentFolderPath}`);
    }

    function createFilePrompt() {
        let name = prompt('Enter file name:');
        if (name) {
            createFile(currentFolderPath, name);
        }
    }

    function createFolderPrompt() {
        let name = prompt('Enter folder name:');
        if (name) {
            createFolder(currentFolderPath, name);
        }
    }

    renderFileSystem();
</script>

</body>
</html>