Dev #5

Merged
sandrodach merged 19 commits from dev into main 2026-10-26 13:35:00 +01:00
Showing only changes of commit 3fcd164fd8 - Show all commits
+135 -126
View File
@@ -3189,119 +3189,9 @@ export const WorkspaceView: React.FC<WorkspaceViewProps> = ({
const isEmpty = docs.length === 0 && allFolderPaths.length === 0; const isEmpty = docs.length === 0 && allFolderPaths.length === 0;
return ( const renderExplorerBody = () => (
<div className="w-full space-y-2">
{/* Top Navigation Mode Switcher: Notizen & Outliner vs. Globales To-Do Dashboard (Desktop) */}
<div className="hidden sm:flex flex-wrap items-center justify-between gap-2 border-b border-border pb-2">
<div className="flex items-center gap-1">
<button
type="button"
onClick={() => setWorkspaceMode('editor')}
className={`h-8 px-3 text-xs font-medium border rounded-btn flex items-center gap-1.5 transition-colors ${
workspaceMode === 'editor'
? 'bg-panel border-accent text-main'
: 'bg-canvas border-border text-muted hover:text-main'
}`}
>
<Layers className="w-3.5 h-3.5 text-accent" />
<span>Notizen</span>
</button>
<button
type="button"
onClick={() => setWorkspaceMode('tags')}
className={`h-8 px-3 text-xs font-medium border rounded-btn flex items-center gap-1.5 transition-colors ${
workspaceMode === 'tags'
? 'bg-panel border-accent text-main'
: 'bg-canvas border-border text-muted hover:text-main'
}`}
>
<Hash className="w-3.5 h-3.5 text-accent" />
<span>Themen & Hashtags</span>
{workspaceTags.length > 0 && (
<span className="badge-neutral font-mono text-[10px]">
{workspaceTags.length}
</span>
)}
</button>
<button
type="button"
onClick={() => setWorkspaceMode('todos')}
className={`h-8 px-3 text-xs font-medium border rounded-btn flex items-center gap-1.5 transition-colors ${
workspaceMode === 'todos'
? 'bg-panel border-accent text-main'
: 'bg-canvas border-border text-muted hover:text-main'
}`}
>
<CheckSquare className="w-3.5 h-3.5 text-accent" />
<span>Globale To-Dos</span>
<span className="badge-neutral font-mono text-[10px]">
{allWorkspaceTodos.filter((t) => !t.block.checked).length}
</span>
</button>
</div>
<div className="flex items-center gap-2 text-xs text-muted">
{workspaceMode === 'editor' && selectedDoc && (
<> <>
<span className="badge-accent"> <div className="p-2.5 sm:p-2 panel-header space-y-2 flex-shrink-0">
<Check className="w-3 h-3" />
{saveState === 'saving' ? 'Speichert…' : 'Gespeichert'}
</span>
<button
type="button"
onClick={handleExportMarkdown}
className="btn-action h-8 px-2.5 text-xs flex items-center gap-1.5"
title="Als Logseq/Markdown-Datei (.md) herunterladen"
>
<Download className="w-3.5 h-3.5 text-accent" />
<span>Export (.md)</span>
</button>
</>
)}
</div>
</div>
{/* ===================================================================== */}
{/* VIEW MODE 1: LOGSEQ OUTLINER & EXPLORER */}
{/* ===================================================================== */}
{workspaceMode === 'editor' && (
<div className="grid grid-cols-1 lg:grid-cols-12 gap-2">
{/* Mobile Backdrop for File Tree Slide-Over Drawer */}
{showMobileFileDrawer && (
<div
className="fixed inset-0 !m-0 bg-black/50 backdrop-blur-xs z-40 lg:hidden animate-in fade-in duration-150"
onClick={() => setShowMobileFileDrawer(false)}
/>
)}
{/* Left Document & Folder Explorer Tree (Desktop Sidebar + Mobile Slide-Over Drawer) */}
<div
className={`${
showMobileFileDrawer
? 'fixed inset-y-0 left-0 z-50 w-[86vw] max-w-sm bg-panel border-r border-border shadow-2xl flex'
: 'hidden lg:flex'
} lg:col-span-4 panel-surface flex-col self-start max-h-screen lg:max-h-none`}
>
{/* Mobile Drawer Top Header */}
<div className="flex lg:hidden items-center justify-between px-3.5 py-3 border-b border-border bg-panel">
<div className="flex items-center gap-2">
<FolderTree className="w-4 h-4 text-accent" />
<span className="text-sm font-bold text-main">Dateibaum & Ordner</span>
</div>
<button
type="button"
onClick={() => setShowMobileFileDrawer(false)}
className="p-1.5 text-muted hover:text-main rounded-btn"
title="Schließen"
>
<X className="w-5 h-5" />
</button>
</div>
<div className="p-2.5 sm:p-2 panel-header space-y-2">
<div className="relative"> <div className="relative">
<Search className="w-4 h-4 sm:w-3.5 sm:h-3.5 text-muted absolute left-2.5 top-1/2 -translate-y-1/2" /> <Search className="w-4 h-4 sm:w-3.5 sm:h-3.5 text-muted absolute left-2.5 top-1/2 -translate-y-1/2" />
<input <input
@@ -3320,7 +3210,7 @@ export const WorkspaceView: React.FC<WorkspaceViewProps> = ({
setShowMobileFileDrawer(false); setShowMobileFileDrawer(false);
handleCreateDoc(null); handleCreateDoc(null);
}} }}
className="flex-1 btn-action min-h-[38px] sm:min-h-0 justify-center" className="flex-1 btn-action min-h-[38px] sm:min-h-0 justify-center cursor-pointer"
title="Neue Datei erstellen" title="Neue Datei erstellen"
> >
<FilePlus className="w-4 h-4 sm:w-3.5 sm:h-3.5 text-muted" /> <FilePlus className="w-4 h-4 sm:w-3.5 sm:h-3.5 text-muted" />
@@ -3330,7 +3220,7 @@ export const WorkspaceView: React.FC<WorkspaceViewProps> = ({
<button <button
type="button" type="button"
onClick={() => handleStartCreateFolder(null)} onClick={() => handleStartCreateFolder(null)}
className="flex-1 btn-action min-h-[38px] sm:min-h-0 justify-center" className="flex-1 btn-action min-h-[38px] sm:min-h-0 justify-center cursor-pointer"
title="Neuen Ordner erstellen" title="Neuen Ordner erstellen"
> >
<FolderPlus className="w-4 h-4 sm:w-3.5 sm:h-3.5 text-muted" /> <FolderPlus className="w-4 h-4 sm:w-3.5 sm:h-3.5 text-muted" />
@@ -3340,7 +3230,7 @@ export const WorkspaceView: React.FC<WorkspaceViewProps> = ({
</div> </div>
{isCreatingFolder && newFolderParent === null && ( {isCreatingFolder && newFolderParent === null && (
<div className="p-2 panel-header bg-canvas flex items-center gap-1.5"> <div className="p-2 panel-header bg-canvas flex items-center gap-1.5 flex-shrink-0">
<Folder className="w-4 h-4 sm:w-3.5 sm:h-3.5 text-muted flex-shrink-0" /> <Folder className="w-4 h-4 sm:w-3.5 sm:h-3.5 text-muted flex-shrink-0" />
<input <input
type="text" type="text"
@@ -3357,26 +3247,25 @@ export const WorkspaceView: React.FC<WorkspaceViewProps> = ({
<button <button
type="button" type="button"
onClick={handleConfirmCreateFolder} onClick={handleConfirmCreateFolder}
className="p-1.5 sm:p-1 text-accent hover:text-main rounded-btn" className="p-1.5 sm:p-1 text-accent hover:text-main rounded-btn cursor-pointer"
title="Bestätigen"
> >
<Check className="w-4 h-4 sm:w-3.5 sm:h-3.5" /> <Check className="w-4 h-4 sm:w-3 sm:h-3" />
</button> </button>
<button <button
type="button" type="button"
onClick={() => setIsCreatingFolder(false)} onClick={() => setIsCreatingFolder(false)}
className="p-1.5 sm:p-1 text-muted hover:text-main rounded-btn" className="p-1.5 sm:p-1 text-muted hover:text-main rounded-btn cursor-pointer"
title="Abbrechen"
> >
<X className="w-4 h-4 sm:w-3.5 sm:h-3.5" /> <X className="w-4 h-4 sm:w-3 sm:h-3" />
</button> </button>
</div> </div>
)} )}
{/* Empty workspace state */}
{isEmpty ? ( {isEmpty ? (
<div className="p-6 my-3 mx-2 border border-dashed border-border bg-canvas/50 text-center rounded-card"> <div className="p-4 text-center text-xs text-muted space-y-2 flex-1">
<Folder className="w-7 h-7 text-faint mx-auto mb-2" /> <Folder className="w-8 h-8 text-faint mx-auto" />
<h5 className="text-xs font-semibold text-muted mb-1">Keine Dateien vorhanden</h5> <p className="font-semibold text-main">Noch keine Notizen</p>
<p className="text-[11px] text-faint mb-3 max-w-xs mx-auto leading-relaxed"> <p className="text-[11px] text-faint mb-3 max-w-xs mx-auto leading-relaxed">
Erstelle eine neue Datei oder lege Ordner an, um deine Dokumente übersichtlich zu strukturieren. Erstelle eine neue Datei oder lege Ordner an, um deine Dokumente übersichtlich zu strukturieren.
</p> </p>
@@ -3387,7 +3276,7 @@ export const WorkspaceView: React.FC<WorkspaceViewProps> = ({
setShowMobileFileDrawer(false); setShowMobileFileDrawer(false);
handleCreateDoc(null); handleCreateDoc(null);
}} }}
className="btn-action min-h-[38px] sm:min-h-0" className="btn-action min-h-[38px] sm:min-h-0 cursor-pointer"
> >
<FilePlus className="w-3.5 h-3.5 text-muted" /> <FilePlus className="w-3.5 h-3.5 text-muted" />
<span>Neue Datei</span> <span>Neue Datei</span>
@@ -3395,7 +3284,7 @@ export const WorkspaceView: React.FC<WorkspaceViewProps> = ({
<button <button
type="button" type="button"
onClick={() => handleStartCreateFolder(null)} onClick={() => handleStartCreateFolder(null)}
className="btn-action min-h-[38px] sm:min-h-0" className="btn-action min-h-[38px] sm:min-h-0 cursor-pointer"
> >
<FolderPlus className="w-3.5 h-3.5 text-muted" /> <FolderPlus className="w-3.5 h-3.5 text-muted" />
<span>Neuer Ordner</span> <span>Neuer Ordner</span>
@@ -3569,8 +3458,128 @@ export const WorkspaceView: React.FC<WorkspaceViewProps> = ({
)} )}
</div> </div>
)} )}
</>
);
return (
<div className="w-full space-y-2">
{/* Top Navigation Mode Switcher: Notizen & Outliner vs. Globales To-Do Dashboard (Desktop) */}
<div className="hidden sm:flex flex-wrap items-center justify-between gap-2 border-b border-border pb-2">
<div className="flex items-center gap-1">
<button
type="button"
onClick={() => setWorkspaceMode('editor')}
className={`h-8 px-3 text-xs font-medium border rounded-btn flex items-center gap-1.5 transition-colors ${
workspaceMode === 'editor'
? 'bg-panel border-accent text-main'
: 'bg-canvas border-border text-muted hover:text-main'
}`}
>
<Layers className="w-3.5 h-3.5 text-accent" />
<span>Notizen</span>
</button>
<button
type="button"
onClick={() => setWorkspaceMode('tags')}
className={`h-8 px-3 text-xs font-medium border rounded-btn flex items-center gap-1.5 transition-colors ${
workspaceMode === 'tags'
? 'bg-panel border-accent text-main'
: 'bg-canvas border-border text-muted hover:text-main'
}`}
>
<Hash className="w-3.5 h-3.5 text-accent" />
<span>Themen & Hashtags</span>
{workspaceTags.length > 0 && (
<span className="badge-neutral font-mono text-[10px]">
{workspaceTags.length}
</span>
)}
</button>
<button
type="button"
onClick={() => setWorkspaceMode('todos')}
className={`h-8 px-3 text-xs font-medium border rounded-btn flex items-center gap-1.5 transition-colors ${
workspaceMode === 'todos'
? 'bg-panel border-accent text-main'
: 'bg-canvas border-border text-muted hover:text-main'
}`}
>
<CheckSquare className="w-3.5 h-3.5 text-accent" />
<span>Globale To-Dos</span>
<span className="badge-neutral font-mono text-[10px]">
{allWorkspaceTodos.filter((t) => !t.block.checked).length}
</span>
</button>
</div> </div>
<div className="flex items-center gap-2 text-xs text-muted">
{workspaceMode === 'editor' && selectedDoc && (
<>
<span className="badge-accent">
<Check className="w-3 h-3" />
{saveState === 'saving' ? 'Speichert…' : 'Gespeichert'}
</span>
<button
type="button"
onClick={handleExportMarkdown}
className="btn-action h-8 px-2.5 text-xs flex items-center gap-1.5"
title="Als Logseq/Markdown-Datei (.md) herunterladen"
>
<Download className="w-3.5 h-3.5 text-accent" />
<span>Export (.md)</span>
</button>
</>
)}
</div>
</div>
{/* ===================================================================== */}
{/* VIEW MODE 1: LOGSEQ OUTLINER & EXPLORER */}
{/* ===================================================================== */}
{workspaceMode === 'editor' && (
<div className="grid grid-cols-1 lg:grid-cols-12 gap-2">
{/* Mobile Centered Floating Explorer Dialog ("in der Mitte schweben") */}
{showMobileFileDrawer && (
<div
className="fixed inset-0 !m-0 z-50 flex items-center justify-center p-3.5 sm:p-4 bg-black/60 backdrop-blur-xs lg:hidden animate-in fade-in duration-150"
onClick={() => setShowMobileFileDrawer(false)}
>
<div
className="w-full max-w-md max-h-[85vh] bg-panel border border-border rounded-2xl shadow-panel flex flex-col overflow-hidden animate-in zoom-in-95 duration-150"
onClick={(e) => e.stopPropagation()}
>
{/* Mobile Dialog Header */}
<div className="flex items-center justify-between px-4 py-3 border-b border-border bg-panel flex-shrink-0">
<div className="flex items-center gap-2">
<div className="w-7 h-7 rounded-btn bg-accent/15 text-accent flex items-center justify-center">
<FolderTree className="w-4 h-4" />
</div>
<span className="text-sm font-semibold text-main">Dateibaum & Ordner</span>
</div>
<button
type="button"
onClick={() => setShowMobileFileDrawer(false)}
className="p-1.5 text-faint hover:text-main rounded-btn transition-colors cursor-pointer"
title="Schließen"
>
<X className="w-5 h-5" />
</button>
</div>
<div className="flex-1 overflow-y-auto flex flex-col">
{renderExplorerBody()}
</div>
</div>
</div>
)}
{/* Desktop Left Document & Folder Explorer Tree (Sidebar) */}
<div className="hidden lg:flex lg:col-span-4 panel-surface flex-col self-start max-h-screen lg:max-h-none">
{renderExplorerBody()}
</div>
{/* Right Logseq Outliner Editor */} {/* Right Logseq Outliner Editor */}
<div className="lg:col-span-8"> <div className="lg:col-span-8">
{selectedDoc ? ( {selectedDoc ? (