mirror of
https://github.com/johndoe6345789/metabuilder.git
synced 2026-05-02 17:55:07 +00:00
dc982772af
## Phase 1: Monolithic File Refactoring ✅ - Refactored 8 large files (300-500 LOC) into 40+ modular components/hooks - All files now <150 LOC per file (max 125 LOC) - CanvasSettings: 343 → 7 components - SecuritySettings: 273 → 6 components - NotificationSettings: 239 → 6 components - Editor/Toolbar: 258 → 7 components - InfiniteCanvas: 239 → 10 modules - WorkflowCard: 320 → 5 components + custom hook - useProjectCanvas: 322 → 8 hooks - projectSlice: 335 → 4 Redux slices ## Phase 2: Business Logic Extraction ✅ - Extracted logic from 5 components into 8 custom hooks - register/page.tsx: 235 → 167 LOC (-29%) - login/page.tsx: 137 → 100 LOC (-27%) - MainLayout.tsx: 216 → 185 LOC (-14%) - ProjectSidebar.tsx: 200 → 200 LOC (refactored) - page.tsx (Dashboard): 197 → 171 LOC (-13%) - New hooks: useAuthForm, usePasswordValidation, useLoginLogic, useRegisterLogic, useHeaderLogic, useResponsiveSidebar, useProjectSidebarLogic, useDashboardLogic ## Phase 3: Dead Code Analysis & Implementation ✅ - Identified and documented 3 unused hooks (244 LOC) - Removed useRealtimeService from exports - Cleaned 8 commented lines in useProject.ts - Documented useExecution stub methods - Removed 3 commented dispatch calls in useCanvasKeyboard - Fixed 3 'as any' type assertions ## Phase 4: Stub Code Implementation ✅ - Fully implemented useExecution methods: execute(), stop(), getDetails(), getStats(), getHistory() - Integrated useCanvasKeyboard into InfiniteCanvas with Redux dispatch - Verified useCanvasVirtualization for 100+ items - Enhanced useRealtimeService documentation for Phase 4 WebSocket integration ## Backend Updates - Added SQLAlchemy models: Workspace, Project, ProjectCanvasItem - Added Flask API endpoints for CRUD operations - Configured multi-tenant filtering for all queries - Added database migrations for new entities ## Build Verification ✅ - TypeScript strict mode: 0 errors - Production build: ✅ Successful (161 kB First Load JS) - No breaking changes - 100% backward compatibility maintained ## Documentation Generated - 6 comprehensive guides (70+ KB total) - Test templates for all new implementations - Quick reference for all 42 hooks - Implementation checklist and deployment guide Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
95 lines
2.5 KiB
TypeScript
95 lines
2.5 KiB
TypeScript
/**
|
|
* useProjectSidebarLogic Hook
|
|
* Business logic for project sidebar including project operations
|
|
*/
|
|
|
|
import { useState, useCallback, useMemo } from 'react';
|
|
import { Project } from '../types/project';
|
|
|
|
export interface UseProjectSidebarLogicReturn {
|
|
isCollapsed: boolean;
|
|
showNewProjectForm: boolean;
|
|
newProjectName: string;
|
|
starredProjects: Project[];
|
|
regularProjects: Project[];
|
|
setIsCollapsed: (collapsed: boolean) => void;
|
|
toggleCollapsed: () => void;
|
|
setShowNewProjectForm: (show: boolean) => void;
|
|
setNewProjectName: (name: string) => void;
|
|
handleCreateProject: (e: React.FormEvent, onSuccess: () => void) => Promise<void>;
|
|
handleProjectClick: (projectId: string, onSelect: (id: string) => void) => void;
|
|
resetProjectForm: () => void;
|
|
}
|
|
|
|
/**
|
|
* Custom hook for project sidebar logic
|
|
* Manages project filtering, form state, and project operations
|
|
*/
|
|
export const useProjectSidebarLogic = (projects: Project[]): UseProjectSidebarLogicReturn => {
|
|
const [isCollapsed, setIsCollapsed] = useState(false);
|
|
const [showNewProjectForm, setShowNewProjectForm] = useState(false);
|
|
const [newProjectName, setNewProjectName] = useState('');
|
|
|
|
// Memoized project filtering
|
|
const starredProjects = useMemo(
|
|
() => projects.filter((p) => p.starred),
|
|
[projects]
|
|
);
|
|
|
|
const regularProjects = useMemo(
|
|
() => projects.filter((p) => !p.starred),
|
|
[projects]
|
|
);
|
|
|
|
const toggleCollapsed = useCallback(() => {
|
|
setIsCollapsed((prev) => !prev);
|
|
}, []);
|
|
|
|
const resetProjectForm = useCallback(() => {
|
|
setShowNewProjectForm(false);
|
|
setNewProjectName('');
|
|
}, []);
|
|
|
|
const handleCreateProject = useCallback(
|
|
async (e: React.FormEvent, onSuccess: () => void) => {
|
|
e.preventDefault();
|
|
|
|
if (!newProjectName.trim()) {
|
|
return;
|
|
}
|
|
|
|
try {
|
|
// This would call the createProject from useProject hook
|
|
// Caller should handle the actual API call
|
|
await onSuccess?.();
|
|
resetProjectForm();
|
|
} catch (error) {
|
|
console.error('Failed to create project:', error);
|
|
}
|
|
},
|
|
[newProjectName, resetProjectForm]
|
|
);
|
|
|
|
const handleProjectClick = useCallback(
|
|
(projectId: string, onSelect: (id: string) => void) => {
|
|
onSelect(projectId);
|
|
},
|
|
[]
|
|
);
|
|
|
|
return {
|
|
isCollapsed,
|
|
showNewProjectForm,
|
|
newProjectName,
|
|
starredProjects,
|
|
regularProjects,
|
|
setIsCollapsed,
|
|
toggleCollapsed,
|
|
setShowNewProjectForm,
|
|
setNewProjectName,
|
|
handleCreateProject,
|
|
handleProjectClick,
|
|
resetProjectForm
|
|
};
|
|
};
|