diff --git a/frontend/src/routes/teacher/content/+page.svelte b/frontend/src/routes/teacher/content/+page.svelte index 1259f00..30b448e 100644 --- a/frontend/src/routes/teacher/content/+page.svelte +++ b/frontend/src/routes/teacher/content/+page.svelte @@ -132,7 +132,16 @@ ].filter((t) => t.show !== false) ); - let allTabs = $derived([{ id: 'files', label: 'Files' }, ...contentTabs]); + // Label tab "Files": saat ada file aktif, tampilkan status + nama file + // (menggantikan baris pinned di rail yang memakan ruang horizontal). + let filesTabLabel = $derived.by(() => { + if (!mgr.activePath) return 'Files'; + const name = mgr.activePath.split('/').pop() ?? mgr.activePath; + if (mgr.treeRoot === 'assets') return `🖼️ ${name}`; + return `${mgr.dirty ? '●' : '✓'} ${name}`; + }); + + let allTabs = $derived([{ id: 'files', label: filesTabLabel }, ...contentTabs]); // Auto-select: setelah preview file aktif selesai dimuat, pindah ke tab // konten pertama file itu (skip 'files'). Tanpa tab konten → tetap Files. @@ -208,6 +217,7 @@ if (mgr.dirty && !window.confirm('Ada perubahan yang belum disimpan. Lanjut buka file lain?')) { return; } + ensureMobileWorkspace(); if (mgr.treeRoot === 'assets') { // Asset file: load for preview only, don't go through draft system mgr.activePath = path; @@ -231,9 +241,6 @@ mgr.activeTab = 'files'; await mgr.loadDraft(path); } - if (mgr.isMobile) { - mgr.mobileMode = mgr.treeRoot === 'assets' ? 'h50' : 'peek'; - } } function handleEditorChange(value: string) { @@ -351,6 +358,18 @@ await mgr.handlePublish(); } + /** + * Mobile: pastikan bottom-sheet cukup tinggi untuk menampilkan tab, rail + * tools, dan tree. Mode `hidden`/`peek`/`h30` terlalu sempit — naikkan ke + * h50 minimal saat user membuka tab / memilih file. + */ + function ensureMobileWorkspace() { + if (!mgr.isMobile) return; + if (mgr.mobileMode === 'hidden' || mgr.mobileMode === 'peek' || mgr.mobileMode === 'h30') { + mgr.mobileMode = 'h50'; + } + } + function handleTabClick(tab: string) { if (mgr.activeTab === 'velxio' && tab !== 'velxio') { syncVelxioToMarkdown(); @@ -358,9 +377,7 @@ // Pilihan manual user membatalkan auto-select yang masih menunggu preview. autoSelectPath = null; mgr.activeTab = tab; - if (mgr.isMobile && mgr.mobileMode === 'hidden') { - mgr.mobileMode = 'h50'; - } + ensureMobileWorkspace(); } // Step the mobile workspace height up/down through the available modes @@ -1035,6 +1052,8 @@ + {:else if mgr.activePath && isAssetFile} + {/if} {/snippet} @@ -1072,68 +1091,47 @@ {#snippet toolsRail()} - {#if mgr.activePath} + {#if mgr.activePath && !isAssetFile} +
- -
- {isAssetFile ? '🖼️' : '📄'} {activeFileName} - {#if isAssetFile} - /assets/{mgr.activePath} - - {:else} - {mgr.dirty ? '● Belum disimpan' : '✓ Tersimpan'} - - - - {/if} -
+
+ - {#if !isAssetFile} - -
- - - -
- 📐 Layout - {#each FEATURE_TEMPLATES.filter(t => t.group === 'layout') as tpl} - - {/each} -
- - - - -
- 🎯 Set Soal - {#each FEATURE_TEMPLATES.filter(t => t.group === 'set_soal') as tpl} - - {/each} -
- - - - -
- ⚡ Inline - {#each FEATURE_TEMPLATES.filter(t => t.group === 'inline') as tpl} - - {/each} -
+ +
+ 📐 Layout + {#each FEATURE_TEMPLATES.filter(t => t.group === 'layout') as tpl} + + {/each}
- {/if} + + + + +
+ 🎯 Set Soal + {#each FEATURE_TEMPLATES.filter(t => t.group === 'set_soal') as tpl} + + {/each} +
+ + + + +
+ ⚡ Inline + {#each FEATURE_TEMPLATES.filter(t => t.group === 'inline') as tpl} + + {/each} +
+
{/if} {/snippet} @@ -1526,6 +1524,9 @@ cursor: pointer; white-space: nowrap; flex-shrink: 0; + max-width: 180px; + overflow: hidden; + text-overflow: ellipsis; margin-bottom: -1px; z-index: 0; transition: background 0.15s, color 0.15s; @@ -1811,44 +1812,6 @@ border-bottom: 1px solid var(--color-border); flex-shrink: 0; } - .qt-pinned { - display: flex; - align-items: center; - gap: 0.35rem; - padding: 0.4rem 0.6rem; - background: var(--color-bg-secondary); - border-right: 1px solid var(--color-border); - flex-shrink: 0; - } - .qt-file-name { - font-size: 0.78rem; - font-weight: 600; - color: var(--color-text); - max-width: 180px; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - } - .qt-path { - font-size: 0.7rem; - color: var(--color-text-muted); - max-width: 200px; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - } - .qt-dirty-badge { - font-size: 0.68rem; - padding: 0.15rem 0.45rem; - border-radius: 4px; - background: #ebfbee; - color: #2b8a3e; - white-space: nowrap; - } - .qt-dirty-badge.dirty { - background: #fff3bf; - color: #e67700; - } .qt-scroll { display: flex; align-items: center; @@ -1909,10 +1872,6 @@ opacity: 0.45; cursor: not-allowed; } - .qt-action-edit { - color: var(--color-primary, #339af0); - font-weight: 600; - } /* Floating mode */ .editor-area.floating { position: fixed;