Upload 20 files
Browse files- static/app.js +5 -0
- static/index.html +18 -11
- static/style.css +3 -3
static/app.js
CHANGED
|
@@ -17,6 +17,7 @@ function hugpanel() {
|
|
| 17 |
currentZone: localStorage.getItem('hugpanel_zone') || null,
|
| 18 |
activeTab: localStorage.getItem('hugpanel_tab') || 'files',
|
| 19 |
maxZones: 0,
|
|
|
|
| 20 |
tabs: [
|
| 21 |
{ id: 'files', label: 'Files', icon: 'folder' },
|
| 22 |
{ id: 'editor', label: 'Editor', icon: 'file-code' },
|
|
@@ -138,6 +139,10 @@ function hugpanel() {
|
|
| 138 |
});
|
| 139 |
});
|
| 140 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 141 |
// Persist session state
|
| 142 |
this.$watch('currentZone', (val) => {
|
| 143 |
if (val) localStorage.setItem('hugpanel_zone', val);
|
|
|
|
| 17 |
currentZone: localStorage.getItem('hugpanel_zone') || null,
|
| 18 |
activeTab: localStorage.getItem('hugpanel_tab') || 'files',
|
| 19 |
maxZones: 0,
|
| 20 |
+
isDesktop: window.innerWidth >= 1280,
|
| 21 |
tabs: [
|
| 22 |
{ id: 'files', label: 'Files', icon: 'folder' },
|
| 23 |
{ id: 'editor', label: 'Editor', icon: 'file-code' },
|
|
|
|
| 139 |
});
|
| 140 |
});
|
| 141 |
|
| 142 |
+
// Track desktop breakpoint
|
| 143 |
+
const mql = window.matchMedia('(min-width: 1280px)');
|
| 144 |
+
mql.addEventListener('change', (e) => { this.isDesktop = e.matches; });
|
| 145 |
+
|
| 146 |
// Persist session state
|
| 147 |
this.$watch('currentZone', (val) => {
|
| 148 |
if (val) localStorage.setItem('hugpanel_zone', val);
|
static/index.html
CHANGED
|
@@ -137,12 +137,18 @@
|
|
| 137 |
<div class="px-2 py-1.5 text-xs font-medium text-gray-500 uppercase tracking-wider">Zones</div>
|
| 138 |
|
| 139 |
<template x-for="zone in zones" :key="zone.name">
|
| 140 |
-
<
|
| 141 |
-
|
| 142 |
-
|
| 143 |
-
|
| 144 |
-
|
| 145 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 146 |
</template>
|
| 147 |
|
| 148 |
<div x-show="zones.length === 0" class="text-center py-8 text-gray-600 text-sm">
|
|
@@ -276,8 +282,9 @@
|
|
| 276 |
<span x-text="currentZone" class="text-sm text-gray-300 font-medium"></span>
|
| 277 |
</div>
|
| 278 |
<span x-text="currentZone" class="text-xs text-gray-500 font-mono mr-2 hidden sm:inline xl:hidden"></span>
|
| 279 |
-
<button @click="confirmDeleteZone()" class="p-1.5 rounded-lg text-gray-500 hover:text-red-400 hover:bg-red-400/10 transition" title="Xoá zone">
|
| 280 |
<i data-lucide="trash-2" class="w-4 h-4"></i>
|
|
|
|
| 281 |
</button>
|
| 282 |
</div>
|
| 283 |
</div>
|
|
@@ -286,8 +293,8 @@
|
|
| 286 |
<!-- ═══ TAB: Files + Editor (split on desktop) ═══ -->
|
| 287 |
<div x-show="activeTab === 'files' || activeTab === 'editor'" class="desktop-split flex-1 flex flex-col xl:flex-row min-h-0">
|
| 288 |
|
| 289 |
-
<!-- Files Panel -->
|
| 290 |
-
<div x-show="activeTab === 'files'" class="split-panel split-files flex
|
| 291 |
|
| 292 |
<!-- File Toolbar -->
|
| 293 |
<div class="px-4 py-2 bg-gray-900/50 border-b border-gray-800 flex flex-wrap items-center gap-2">
|
|
@@ -388,8 +395,8 @@
|
|
| 388 |
</div>
|
| 389 |
</div>
|
| 390 |
|
| 391 |
-
<!-- ═══ TAB: Editor ═══ -->
|
| 392 |
-
<div x-show="activeTab === 'editor'" class="split-panel split-editor flex-1 flex flex-col min-h-0">
|
| 393 |
<div x-show="!editorFile" class="flex-1 flex items-center justify-center text-gray-600 text-sm">
|
| 394 |
Chọn file để chỉnh sửa
|
| 395 |
</div>
|
|
|
|
| 137 |
<div class="px-2 py-1.5 text-xs font-medium text-gray-500 uppercase tracking-wider">Zones</div>
|
| 138 |
|
| 139 |
<template x-for="zone in zones" :key="zone.name">
|
| 140 |
+
<div class="group relative">
|
| 141 |
+
<button @click="selectZone(zone.name); sidebarOpen = false"
|
| 142 |
+
:class="currentZone === zone.name ? 'bg-brand-600/20 text-brand-400 border-brand-500/30' : 'text-gray-400 hover:bg-gray-800 hover:text-gray-200 border-transparent'"
|
| 143 |
+
class="w-full flex items-center gap-2.5 px-3 py-2 rounded-lg text-sm transition-all border">
|
| 144 |
+
<i data-lucide="box" class="w-4 h-4 flex-shrink-0"></i>
|
| 145 |
+
<span x-text="zone.name" class="truncate"></span>
|
| 146 |
+
</button>
|
| 147 |
+
<button @click.stop="currentZone = zone.name; confirmDeleteZone()"
|
| 148 |
+
class="absolute right-2 top-1/2 -translate-y-1/2 p-1 rounded text-gray-600 hover:text-red-400 hover:bg-red-400/10 opacity-0 group-hover:opacity-100 transition" title="Xoá zone">
|
| 149 |
+
<i data-lucide="trash-2" class="w-3.5 h-3.5"></i>
|
| 150 |
+
</button>
|
| 151 |
+
</div>
|
| 152 |
</template>
|
| 153 |
|
| 154 |
<div x-show="zones.length === 0" class="text-center py-8 text-gray-600 text-sm">
|
|
|
|
| 282 |
<span x-text="currentZone" class="text-sm text-gray-300 font-medium"></span>
|
| 283 |
</div>
|
| 284 |
<span x-text="currentZone" class="text-xs text-gray-500 font-mono mr-2 hidden sm:inline xl:hidden"></span>
|
| 285 |
+
<button @click="confirmDeleteZone()" class="p-1.5 rounded-lg text-gray-500 hover:text-red-400 hover:bg-red-400/10 transition flex items-center gap-1.5" title="Xoá zone">
|
| 286 |
<i data-lucide="trash-2" class="w-4 h-4"></i>
|
| 287 |
+
<span class="hidden xl:inline text-xs">Xoá zone</span>
|
| 288 |
</button>
|
| 289 |
</div>
|
| 290 |
</div>
|
|
|
|
| 293 |
<!-- ═══ TAB: Files + Editor (split on desktop) ═══ -->
|
| 294 |
<div x-show="activeTab === 'files' || activeTab === 'editor'" class="desktop-split flex-1 flex flex-col xl:flex-row min-h-0">
|
| 295 |
|
| 296 |
+
<!-- Files Panel (always visible on desktop when in files/editor tab) -->
|
| 297 |
+
<div x-show="activeTab === 'files' || (isDesktop && activeTab === 'editor')" class="split-panel split-files flex flex-col min-h-0" :class="isDesktop ? '' : 'flex-1'">
|
| 298 |
|
| 299 |
<!-- File Toolbar -->
|
| 300 |
<div class="px-4 py-2 bg-gray-900/50 border-b border-gray-800 flex flex-wrap items-center gap-2">
|
|
|
|
| 395 |
</div>
|
| 396 |
</div>
|
| 397 |
|
| 398 |
+
<!-- ═══ TAB: Editor (always visible on desktop when in files/editor tab) ═══ -->
|
| 399 |
+
<div x-show="activeTab === 'editor' || (isDesktop && activeTab === 'files')" class="split-panel split-editor flex-1 flex flex-col min-h-0">
|
| 400 |
<div x-show="!editorFile" class="flex-1 flex items-center justify-center text-gray-600 text-sm">
|
| 401 |
Chọn file để chỉnh sửa
|
| 402 |
</div>
|
static/style.css
CHANGED
|
@@ -94,10 +94,10 @@ input:focus, textarea:focus, button:focus-visible {
|
|
| 94 |
|
| 95 |
/* ═══ Desktop Enhancements ═══ */
|
| 96 |
|
| 97 |
-
/* Desktop split:
|
| 98 |
@media (min-width: 1280px) {
|
| 99 |
-
.desktop-split
|
| 100 |
-
|
| 101 |
}
|
| 102 |
.desktop-split > .split-files {
|
| 103 |
width: 380px;
|
|
|
|
| 94 |
|
| 95 |
/* ═══ Desktop Enhancements ═══ */
|
| 96 |
|
| 97 |
+
/* Desktop split: files + editor side by side on xl+ */
|
| 98 |
@media (min-width: 1280px) {
|
| 99 |
+
.desktop-split {
|
| 100 |
+
flex-direction: row !important;
|
| 101 |
}
|
| 102 |
.desktop-split > .split-files {
|
| 103 |
width: 380px;
|