diff --git a/README.md b/README.md index 57e7b25..139119b 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,78 @@ # Open Source WorkFlow -please support this project -`workflow` is a project for managing all the tasks of devs like - -1. creating project -2. installing libraries -3. using opensource code blocks -4. removing import export bloatware -5. follow DNR (do not show repeating) -6. get the complexity and rendering of code at time -7. be a 10x dev with the help of workflow + +๐Ÿš€ **10x Developer Workflow Tool** - Supercharge your development productivity! + +`workflow` is a comprehensive project for managing all development tasks and becoming a 10x developer with powerful workflow automation. + +## ๐ŸŽฏ Features + +### โœ… Implemented Core Features +1. **๐Ÿ—๏ธ Creating Project** - Scaffold new projects with popular templates (Next.js, React, Vue, Node.js, Express) +2. **๐Ÿ“ฆ Installing Libraries** - Smart package manager integration with popular library suggestions +3. **๐Ÿงฉ Using Opensource Code Blocks** - Searchable code snippet library with syntax highlighting +4. **๐Ÿงน Removing Import/Export Bloatware** - Automated cleanup of unused imports and code bloat +5. **๐Ÿšซ Follow DNR (Do Not Repeat)** - Advanced duplicate code detection and analysis +6. **๐Ÿ“Š Get Complexity and Rendering Analysis** - Real-time code complexity metrics and performance analysis +7. **โšก 10x Developer Productivity** - All-in-one workflow interface for maximum efficiency + +### ๐Ÿ› ๏ธ Additional Features +- **File Browser** - Navigate and explore project directories +- **VS Code Integration** - One-click project opening +- **Real-time Analysis** - Performance, complexity, and code quality metrics +- **Template Management** - Create and manage reusable code templates +- **Smart Suggestions** - Popular packages and best practices recommendations + +## ๐Ÿš€ Getting Started + +### Prerequisites +- Node.js 16+ +- npm/yarn/pnpm + +### Installation +```bash +git clone +cd workflow +npm install +``` + +### Development +```bash +npm run dev +``` + +### Production +```bash +npm run build +npm start +``` + +## ๐ŸŽฎ Usage + +1. **Set your project path** in the input field +2. **Choose your workflow action**: + - **Create Project**: Select template and generate new project structure + - **Install Libraries**: Add dependencies with smart package suggestions + - **Code Blocks**: Browse and use opensource code templates + - **Analyze Code**: Get complexity metrics, performance insights, and duplicate detection + +## ๐Ÿ—๏ธ Architecture + +- **Frontend**: Next.js 13 + TypeScript + Chakra UI +- **Backend**: Next.js API Routes with Node.js child processes +- **Features**: File system operations, package management, code analysis +- **UI**: Responsive design with modals and real-time feedback + +## ๐Ÿ“ˆ Code Quality Features + +- **Complexity Analysis**: Cyclomatic complexity and maintainability index +- **Performance Metrics**: Nested loops, DOM queries, sync operations detection +- **Import Analysis**: Unused import detection and cleanup +- **Duplicate Detection**: DNR compliance checking with line-by-line analysis + +## ๐Ÿค Contributing + +Please support this project! Contributions, issues, and feature requests are welcome. + +## ๐Ÿ“„ License + +Open Source - feel free to use and modify for your development workflow needs. diff --git a/assets/codeblocks.json b/assets/codeblocks.json new file mode 100644 index 0000000..d3dea1e --- /dev/null +++ b/assets/codeblocks.json @@ -0,0 +1,30 @@ +{ + "blocks": [ + { + "id": "react-component", + "title": "React Functional Component", + "description": "Basic React functional component template", + "code": "import React from 'react';\n\ninterface Props {\n // Define your props here\n}\n\nconst ComponentName: React.FC = ({ }) => {\n return (\n
\n {/* Your JSX here */}\n
\n );\n};\n\nexport default ComponentName;", + "language": "typescript", + "tags": [ + "react", + "component", + "typescript" + ], + "category": "react" + }, + { + "id": "api-route", + "title": "Next.js API Route", + "description": "Basic Next.js API route template", + "code": "import type { NextApiRequest, NextApiResponse } from \"next\";\n\nexport default function handler(\n req: NextApiRequest,\n res: NextApiResponse\n) {\n switch (req.method) {\n case \"GET\":\n res.status(200).json({ message: \"GET request\" });\n break;\n case \"POST\":\n res.status(200).json({ message: \"POST request\" });\n break;\n default:\n res.status(405).json({ error: \"Method not allowed\" });\n }\n}", + "language": "typescript", + "tags": [ + "nextjs", + "api", + "typescript" + ], + "category": "api" + } + ] +} \ No newline at end of file diff --git a/components/CodeAnalyzer.tsx b/components/CodeAnalyzer.tsx new file mode 100644 index 0000000..0c3b9b4 --- /dev/null +++ b/components/CodeAnalyzer.tsx @@ -0,0 +1,372 @@ +import { + Box, + Button, + Text, + useToast, + Modal, + ModalOverlay, + ModalContent, + ModalHeader, + ModalFooter, + ModalBody, + ModalCloseButton, + useDisclosure, + VStack, + HStack, + Badge, + Progress, + Stat, + StatLabel, + StatNumber, + StatHelpText, + SimpleGrid, + Accordion, + AccordionItem, + AccordionButton, + AccordionPanel, + AccordionIcon, + Select, + Input, + Alert, + AlertIcon, + AlertTitle, + AlertDescription, +} from "@chakra-ui/react"; +import { useState } from "react"; +import axios from "axios"; + +interface Props { + currentPath: string; +} + +interface AnalysisResult { + filePath: string; + analysisType: string; + result: any; + timestamp: string; +} + +const CodeAnalyzer = ({ currentPath }: Props) => { + const { isOpen, onOpen, onClose } = useDisclosure(); + const [filePath, setFilePath] = useState(""); + const [analysisType, setAnalysisType] = useState<"complexity" | "performance" | "imports" | "duplicates">("complexity"); + const [analysisResult, setAnalysisResult] = useState(null); + const [isLoading, setIsLoading] = useState(false); + const toast = useToast(); + + const analysisTypes = [ + { value: "complexity", label: "Code Complexity" }, + { value: "performance", label: "Performance Analysis" }, + { value: "imports", label: "Import/Export Analysis" }, + { value: "duplicates", label: "Duplicate Detection (DNR)" }, + ]; + + const handleAnalysis = async () => { + if (!filePath) { + toast({ + title: "Error", + description: "Please enter a file path", + status: "error", + duration: 3000, + }); + return; + } + + setIsLoading(true); + try { + const response = await axios.post("/api/analysis", { + filePath: `${currentPath}/${filePath}`, + analysisType, + }); + + setAnalysisResult(response.data); + toast({ + title: "Analysis Complete", + description: `${analysisType} analysis completed successfully`, + status: "success", + duration: 3000, + }); + } catch (error: any) { + toast({ + title: "Analysis Failed", + description: error.response?.data?.details || "Failed to analyze file", + status: "error", + duration: 5000, + }); + } + setIsLoading(false); + }; + + const renderComplexityResults = (result: any) => ( + + + Total Lines + {result.totalLines} + + + Code Lines + {result.codeLines} + + + Functions + {result.functions} + + + Conditionals + {result.conditionals} + + + Cyclomatic Complexity + 10 ? "red.500" : "green.500"}> + {result.cyclomaticComplexity} + + {result.cyclomaticComplexity > 10 ? "High" : "Good"} + + + Maintainability Index + + {result.maintainabilityIndex.toFixed(1)} + + + + + ); + + const renderPerformanceResults = (result: any) => ( + + + + Nested Loops + 0 ? "orange.500" : "green.500"}> + {result.nestedLoops} + + {result.nestedLoops > 0 ? "Consider optimization" : "Good"} + + + DOM Queries + 5 ? "orange.500" : "green.500"}> + {result.domQueries} + + + + Sync Operations + 0 ? "red.500" : "green.500"}> + {result.synchronousOps} + + + + Performance Score + + {result.performanceScore} + + + + + {result.performanceScore < 70 && ( + + + Performance Issues Detected! + + Consider optimizing nested loops, reducing DOM queries, and using async operations. + + + )} + + ); + + const renderImportsResults = (result: any) => ( + + + + Total Imports + {result.totalImports} + + + ES Module Imports + {result.esModuleImports} + + + CommonJS Requires + {result.commonJSRequires} + + + Unused Imports (Bloatware) + 0 ? "red.500" : "green.500"}> + {result.bloatwareScore} + + + + {result.unusedImports.length > 0 && ( + + + Import Bloatware Detected! + + Unused imports: {result.unusedImports.join(", ")} + + + )} + + ); + + const renderDuplicatesResults = (result: any) => ( + + + + Duplicate Lines + 0 ? "orange.500" : "green.500"}> + {result.duplicateCount} + + + + Duplication % + 10 ? "red.500" : "green.500"}> + {result.duplicatePercentage.toFixed(1)}% + + + + {result.duplicateLines.length > 0 && ( + + Duplicate Code Found (DNR Violations): + + {result.duplicateLines.map((duplicate: any, index: number) => ( + + + + + {duplicate.occurrences}x + + {duplicate.content.substring(0, 50)}... + + + + + + + + Found on lines: {duplicate.lines.join(", ")} + + {duplicate.content} + + + + + ))} + + + )} + + ); + + const renderResults = () => { + if (!analysisResult) return null; + + const { result, analysisType } = analysisResult; + + switch (analysisType) { + case "complexity": + return renderComplexityResults(result); + case "performance": + return renderPerformanceResults(result); + case "imports": + return renderImportsResults(result); + case "duplicates": + return renderDuplicatesResults(result); + default: + return Unknown analysis type; + } + }; + + return ( + <> + + + + + + 10x Developer Code Analysis + + + + + setFilePath(e.target.value)} + flex={1} + /> + + + + + + Analyzing: {currentPath}/{filePath} + + + {analysisResult && ( + + + + Analysis Results + + + {analysisResult.analysisType} + + + {renderResults()} + + Analysis completed: {new Date(analysisResult.timestamp).toLocaleString()} + + + )} + + + + + + + + + ); +}; + +export default CodeAnalyzer; \ No newline at end of file diff --git a/components/CodeBlockManager.tsx b/components/CodeBlockManager.tsx new file mode 100644 index 0000000..432e240 --- /dev/null +++ b/components/CodeBlockManager.tsx @@ -0,0 +1,340 @@ +import { + Box, + Button, + Text, + useToast, + Modal, + ModalOverlay, + ModalContent, + ModalHeader, + ModalFooter, + ModalBody, + ModalCloseButton, + useDisclosure, + VStack, + HStack, + Badge, + Accordion, + AccordionItem, + AccordionButton, + AccordionPanel, + AccordionIcon, + Code, + Textarea, + Select, + Input, + Wrap, + WrapItem, +} from "@chakra-ui/react"; +import { useState, useEffect } from "react"; +import axios from "axios"; + +interface CodeBlock { + id: string; + title: string; + description: string; + code: string; + language: string; + tags: string[]; + category: string; +} + +interface Props { + currentPath: string; +} + +const CodeBlockManager = ({ currentPath }: Props) => { + const { isOpen, onOpen, onClose } = useDisclosure(); + const { + isOpen: isAddOpen, + onOpen: onAddOpen, + onClose: onAddClose, + } = useDisclosure(); + + const [codeBlocks, setCodeBlocks] = useState<{ blocks: CodeBlock[] }>({ blocks: [] }); + const [selectedCategory, setSelectedCategory] = useState("all"); + const [searchTerm, setSearchTerm] = useState(""); + const [isLoading, setIsLoading] = useState(false); + + // New code block form + const [newBlock, setNewBlock] = useState({ + title: "", + description: "", + code: "", + language: "javascript", + tags: "", + category: "general", + }); + + const toast = useToast(); + + const fetchCodeBlocks = async () => { + try { + const response = await axios.get("/api/codeblocks"); + setCodeBlocks(response.data); + } catch (error) { + console.error("Failed to fetch code blocks:", error); + } + }; + + useEffect(() => { + fetchCodeBlocks(); + }, []); + + const categories = ["all", ...Array.from(new Set(codeBlocks.blocks.map(block => block.category)))]; + + const filteredBlocks = codeBlocks.blocks.filter((block) => { + const matchesCategory = selectedCategory === "all" || block.category === selectedCategory; + const matchesSearch = + searchTerm === "" || + block.title.toLowerCase().includes(searchTerm.toLowerCase()) || + block.description.toLowerCase().includes(searchTerm.toLowerCase()) || + block.tags.some(tag => tag.toLowerCase().includes(searchTerm.toLowerCase())); + + return matchesCategory && matchesSearch; + }); + + const copyToClipboard = async (code: string, title: string) => { + try { + await navigator.clipboard.writeText(code); + toast({ + title: "Copied!", + description: `${title} code copied to clipboard`, + status: "success", + duration: 2000, + }); + } catch (error) { + toast({ + title: "Error", + description: "Failed to copy code", + status: "error", + duration: 2000, + }); + } + }; + + const handleAddCodeBlock = async () => { + if (!newBlock.title || !newBlock.code) { + toast({ + title: "Error", + description: "Please fill in title and code", + status: "error", + duration: 3000, + }); + return; + } + + setIsLoading(true); + try { + const codeBlockData = { + ...newBlock, + id: Date.now().toString(), + tags: newBlock.tags.split(",").map(tag => tag.trim()).filter(Boolean), + }; + + await axios.post("/api/codeblocks", codeBlockData); + await fetchCodeBlocks(); + + toast({ + title: "Success", + description: "Code block added successfully", + status: "success", + duration: 3000, + }); + + setNewBlock({ + title: "", + description: "", + code: "", + language: "javascript", + tags: "", + category: "general", + }); + onAddClose(); + } catch (error) { + toast({ + title: "Error", + description: "Failed to add code block", + status: "error", + duration: 3000, + }); + } + setIsLoading(false); + }; + + return ( + <> + + + + + + + + Open Source Code Blocks + + + + + + + + setSearchTerm(e.target.value)} + /> + + + + + Found {filteredBlocks.length} code block(s) + + + + {filteredBlocks.map((block) => ( + +

+ + + + {block.title} + {block.language} + {block.category} + + + {block.description} + + + + +

+ + + + {block.tags.map(tag => ( + + + {tag} + + + ))} + + +
{block.code}
+
+ + + +
+
+
+ ))} +
+
+
+ + + +
+
+ + {/* Add New Code Block Modal */} + + + + Add New Code Block + + + + setNewBlock({ ...newBlock, title: e.target.value })} + /> + setNewBlock({ ...newBlock, description: e.target.value })} + /> + + + setNewBlock({ ...newBlock, category: e.target.value })} + /> + + setNewBlock({ ...newBlock, tags: e.target.value })} + /> +