Initial onlyoffice integration, sidebar changes
Some checks failed
Automated Container Build / build-and-push (push) Failing after 28s

This commit is contained in:
Elijah 2026-05-24 10:46:27 -07:00
parent 4110657557
commit d80e31e7f5
7 changed files with 504 additions and 12 deletions

View file

@ -8,7 +8,7 @@ import {
MoreVertical, Star, Download, Pencil, Copy, Move,
FolderPlus, ArrowUp, X, Check, RefreshCw, Info, Link as LinkIcon, Image as ImageIcon, Film as FilmIcon, Home,
Sun, Moon, Music as MusicIcon, Code as CodeIcon, Archive as ArchiveIcon, CornerDownRight,
CheckCircle, AlertCircle, Menu
CheckCircle, AlertCircle, Menu, FileText, Presentation
} from 'lucide-react';
import api from '@/lib/api';
import { useIsMobile } from '@/hooks/useIsMobile';
@ -26,6 +26,8 @@ import TaskManager from './TaskManager';
import ShareModal from './ShareModal';
import FileInfoModal from './FileInfoModal';
import SharedFilesPage from './SharedFilesPage';
import OfficeHome from './OfficeHome';
import OnlyOfficeEditor from './OnlyOfficeEditor';
interface FileItem {
name: string;
@ -237,6 +239,8 @@ export default function FileExplorer({ onLogout }: FileExplorerProps) {
const [files, setFiles] = useState<FileItem[]>([]);
const [loading, setLoading] = useState(true);
const [viewMode, setViewMode] = useState<ViewMode>('grid');
const [appMode, setAppMode] = useState<'drive' | 'docs' | 'slides'>('drive');
const [editingFile, setEditingFile] = useState<FileItem | null>(null);
const [activeSection, setActiveSection] = useState<SidebarSection>('files');
const [searchQuery, setSearchQuery] = useState('');
const [searchResults, setSearchResults] = useState<FileItem[] | null>(null);
@ -548,8 +552,17 @@ export default function FileExplorer({ onLogout }: FileExplorerProps) {
return next;
});
} else {
if (file.is_dir) navigateToFolder(file);
else setPreviewFile(file);
if (file.is_dir) {
navigateToFolder(file);
} else if (file.name.endsWith('.docx')) {
setAppMode('docs');
setEditingFile(file);
} else if (file.name.endsWith('.pptx')) {
setAppMode('slides');
setEditingFile(file);
} else {
setPreviewFile(file);
}
}
}
@ -1300,22 +1313,54 @@ export default function FileExplorer({ onLogout }: FileExplorerProps) {
borderColor: 'var(--color-border-subtle)',
}}
>
<div className="flex items-center gap-3 px-5 py-5">
<div
className="w-9 h-9 rounded-xl flex items-center justify-center"
<div className="flex flex-col gap-1 px-3 py-4 border-b" style={{ borderColor: 'var(--color-border-subtle)' }}>
<button
onClick={() => { setAppMode('drive'); setEditingFile(null); }}
className="w-full flex items-center gap-3 px-3 py-2.5 rounded-xl text-sm font-bold transition-all duration-150"
style={{
background: 'linear-gradient(135deg, var(--color-accent), #8b5cf6)',
backgroundColor: appMode === 'drive' ? 'var(--color-accent-subtle)' : 'transparent',
color: appMode === 'drive' ? 'var(--color-accent)' : 'var(--color-text-primary)',
}}
>
<HardDrive className="w-4.5 h-4.5 text-white" />
</div>
<span className="text-base font-bold" style={{ color: 'var(--color-text-primary)' }}>
<div className="w-7 h-7 rounded-lg flex items-center justify-center" style={{ background: appMode === 'drive' ? 'linear-gradient(135deg, var(--color-accent), #8b5cf6)' : 'var(--color-bg-elevated)' }}>
<HardDrive className={`w-4 h-4 ${appMode === 'drive' ? 'text-white' : ''}`} style={{ color: appMode !== 'drive' ? 'var(--color-text-secondary)' : undefined }} />
</div>
Drive
</span>
</button>
<button
onClick={() => { setAppMode('docs'); setEditingFile(null); }}
className="w-full flex items-center gap-3 px-3 py-2.5 rounded-xl text-sm font-bold transition-all duration-150"
style={{
backgroundColor: appMode === 'docs' ? 'var(--color-accent-subtle)' : 'transparent',
color: appMode === 'docs' ? 'var(--color-accent)' : 'var(--color-text-primary)',
}}
>
<div className="w-7 h-7 rounded-lg flex items-center justify-center" style={{ background: appMode === 'docs' ? 'linear-gradient(135deg, #3b82f6, #2563eb)' : 'var(--color-bg-elevated)' }}>
<FileText className={`w-4 h-4 ${appMode === 'docs' ? 'text-white' : ''}`} style={{ color: appMode !== 'docs' ? 'var(--color-text-secondary)' : undefined }} />
</div>
Docs
</button>
<button
onClick={() => { setAppMode('slides'); setEditingFile(null); }}
className="w-full flex items-center gap-3 px-3 py-2.5 rounded-xl text-sm font-bold transition-all duration-150"
style={{
backgroundColor: appMode === 'slides' ? 'var(--color-accent-subtle)' : 'transparent',
color: appMode === 'slides' ? 'var(--color-accent)' : 'var(--color-text-primary)',
}}
>
<div className="w-7 h-7 rounded-lg flex items-center justify-center" style={{ background: appMode === 'slides' ? 'linear-gradient(135deg, #f59e0b, #d97706)' : 'var(--color-bg-elevated)' }}>
<Presentation className={`w-4 h-4 ${appMode === 'slides' ? 'text-white' : ''}`} style={{ color: appMode !== 'slides' ? 'var(--color-text-secondary)' : undefined }} />
</div>
Slides
</button>
</div>
<nav className="flex-1 px-3 py-2 space-y-1 overflow-y-auto">
<div className="flex flex-col">
{appMode === 'drive' && (
<>
<div className="flex flex-col">
<button
id="nav-files"
onClick={() => { handleSectionChange('files'); navigateTo('.'); }}
@ -1454,6 +1499,42 @@ export default function FileExplorer({ onLogout }: FileExplorerProps) {
{label}
</button>
))}
</>
)}
{appMode === 'docs' && (
<>
<div className="px-3 py-2 text-xs font-semibold uppercase tracking-wider text-gray-500">Documents</div>
<button
onClick={() => { setActiveSection('files'); setEditingFile(null); }}
className="w-full flex items-center gap-3 px-3 py-2.5 rounded-xl text-sm font-medium transition-all duration-150"
style={{
backgroundColor: !editingFile ? 'var(--color-accent-subtle)' : 'transparent',
color: !editingFile ? 'var(--color-accent)' : 'var(--color-text-secondary)',
}}
>
<FileText className="w-4.5 h-4.5" />
Recent Documents
</button>
</>
)}
{appMode === 'slides' && (
<>
<div className="px-3 py-2 text-xs font-semibold uppercase tracking-wider text-gray-500">Presentations</div>
<button
onClick={() => { setActiveSection('files'); setEditingFile(null); }}
className="w-full flex items-center gap-3 px-3 py-2.5 rounded-xl text-sm font-medium transition-all duration-150"
style={{
backgroundColor: !editingFile ? 'var(--color-accent-subtle)' : 'transparent',
color: !editingFile ? 'var(--color-accent)' : 'var(--color-text-secondary)',
}}
>
<Presentation className="w-4.5 h-4.5" />
Recent Presentations
</button>
</>
)}
</nav>
<div className="px-3 py-4 border-t" style={{ borderColor: 'var(--color-border-subtle)' }}>
@ -1481,6 +1562,7 @@ export default function FileExplorer({ onLogout }: FileExplorerProps) {
<header
className="flex items-center gap-4 px-6 py-3.5 border-b"
style={{
display: appMode === 'drive' ? 'flex' : 'none',
backgroundColor: 'var(--color-bg-secondary)',
borderColor: 'var(--color-border-subtle)',
}}
@ -1776,6 +1858,18 @@ export default function FileExplorer({ onLogout }: FileExplorerProps) {
<StorageDashboard />
) : activeSection === 'shared' ? (
<SharedFilesPage />
) : editingFile ? (
<OnlyOfficeEditor
file={editingFile}
type={editingFile.name.endsWith('.docx') ? 'word' : editingFile.name.endsWith('.pptx') ? 'slide' : 'word'}
onClose={() => setEditingFile(null)}
/>
) : (appMode === 'docs' || appMode === 'slides') && activeSection === 'files' ? (
<OfficeHome
type={appMode}
onFileSelect={(file) => setEditingFile(file)}
onCreateBlank={(file) => setEditingFile(file)}
/>
) : (
<div className="flex flex-1 overflow-hidden">
<div