Files
metabuilder/hooks/useProjectSidebarLogic.ts
johndoe6345789 78a54228df feat(hooks): Create centralized hooks npm package
- Added @metabuilder/hooks workspace package at root
- Consolidated 30 React hooks from across codebase into single module
- Implemented conditional exports for tree-shaking support
- Added comprehensive package.json with build/lint/typecheck scripts
- Created README.md documenting hook categories and usage patterns
- Updated root package.json workspaces array to include hooks
- Supports multi-version peer dependencies (React 18/19, Redux 8/9)

Usage:
  import { useDashboardLogic } from '@metabuilder/hooks'
  import { useLoginLogic } from '@metabuilder/hooks/useLoginLogic'

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-01-23 19:17:17 +00:00

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
};
};