CoolFace
Apppublic

admin08077/Githubgemini

sourceHugging Faceotherupdated 10mo agoView on Hugging Face
0likes
AiFeatureBuilder-qJcM7Vps.js.map1 linesDownload Raw Back to assets
1{"version":3,"file":"AiFeatureBuilder-qJcM7Vps.js","sources":["../../components/features/AiFeatureBuilder.tsx"],"sourcesContent":["import React, { useState, useCallback, useEffect } from 'react';\nimport type { GeneratedFile } from '../../types.ts';\nimport { generateFeature, generateUnitTestsStream, generateCommitMessageStream, saveFile, getAllFiles, clearAllFiles } from '../../services/index.ts';\nimport { CpuChipIcon, DocumentTextIcon, BeakerIcon, GitBranchIcon } from '../icons.tsx';\nimport { LoadingSpinner, MarkdownRenderer } from '../shared/index.tsx';\n\ntype ActiveTab = 'CODE' | 'TESTS' | 'COMMIT';\n\nexport const AiFeatureBuilder: React.FC = () => {\n    const [prompt, setPrompt] = useState<string>('A simple \"Hello World\" React component with a button that shows an alert.');\n    const [generatedFiles, setGeneratedFiles] = useState<GeneratedFile[]>([]);\n    const [unitTests, setUnitTests] = useState<string>('');\n    const [commitMessage, setCommitMessage] = useState<string>('');\n    const [selectedFile, setSelectedFile] = useState<GeneratedFile | null>(null);\n    const [isLoading, setIsLoading] = useState<boolean>(false);\n    const [error, setError] = useState<string>('');\n    const [activeTab, setActiveTab] = useState<ActiveTab>('CODE');\n    \n    useEffect(() => {\n        const loadFiles = async () => {\n            const files = await getAllFiles();\n            setGeneratedFiles(files);\n            if (files.length > 0) setSelectedFile(files[0]);\n        };\n        loadFiles();\n    }, []);\n\n    const handleGenerate = useCallback(async () => {\n        if (!prompt.trim()) { setError('Please enter a feature description.'); return; }\n        setIsLoading(true);\n        setError('');\n        await clearAllFiles(); // Start fresh for each generation\n        setGeneratedFiles([]);\n        setUnitTests('');\n        setCommitMessage('');\n        setSelectedFile(null);\n        setActiveTab('CODE');\n\n        try {\n            const resultFiles = await generateFeature(prompt);\n            for (const file of resultFiles) { await saveFile(file); }\n            setGeneratedFiles(resultFiles);\n\n            if (resultFiles.length > 0) {\n                const componentFile = resultFiles.find(f => f.filePath.endsWith('.tsx') || f.filePath.endsWith('.jsx'));\n                setSelectedFile(componentFile || resultFiles[0]);\n\n                if (componentFile) {\n                    const testStream = generateUnitTestsStream(componentFile.content);\n                    let tests = '';\n                    for await (const chunk of testStream) { tests += chunk; setUnitTests(tests); }\n                }\n\n                const diffContext = resultFiles.map(f => `File: ${f.filePath}\\n\\n${f.content}`).join('\\n---\\n');\n                const commitStream = generateCommitMessageStream(diffContext);\n                let commit = '';\n                for await (const chunk of commitStream) { commit += chunk; setCommitMessage(commit); }\n            }\n        } catch (err) {\n            const errorMessage = err instanceof Error ? err.message : 'An unknown error occurred.';\n            setError(`Failed to generate feature: ${errorMessage}`);\n        } finally {\n            setIsLoading(false);\n        }\n    }, [prompt]);\n    \n    const renderContent = () => {\n        switch (activeTab) {\n            case 'TESTS': return <MarkdownRenderer content={unitTests} />;\n            case 'COMMIT': return <pre className=\"w-full h-full p-4 whitespace-pre-wrap font-sans text-sm text-text-primary\">{commitMessage}</pre>;\n            case 'CODE':\n            default:\n                 return selectedFile ? <MarkdownRenderer content={`\\`\\`\\`tsx\\n${selectedFile.content}\\n\\`\\`\\``} /> : <div className=\"flex items-center justify-center h-full text-text-secondary\">Select a file to view its content.</div>;\n        }\n    }\n\n    return (\n        <div className=\"h-full flex flex-col text-text-primary bg-surface\">\n            <header className=\"p-4 border-b border-border flex-shrink-0\">\n                <h1 className=\"text-xl font-bold flex items-center\"><CpuChipIcon /><span className=\"ml-3\">AI Feature Builder</span></h1>\n            </header>\n\n            <div className=\"flex-grow flex min-h-0\">\n                <aside className=\"w-64 bg-surface border-r border-border p-4 flex flex-col\">\n                    <h2 className=\"text-sm font-semibold text-text-secondary mb-2\">Generated Files</h2>\n                    <div className=\"overflow-y-auto space-y-1\">\n                        {generatedFiles.map(file => (\n                            <div key={file.filePath} onClick={() => { setSelectedFile(file); setActiveTab('CODE'); }} className={`flex items-center space-x-2 p-2 rounded-md cursor-pointer text-sm ${selectedFile?.filePath === file.filePath && activeTab === 'CODE' ? 'bg-primary/10 text-primary' : 'hover:bg-gray-100'}`}>\n                                <DocumentTextIcon /><span>{file.filePath.split('/').pop()}</span>\n                            </div>\n                        ))}\n                    </div>\n                </aside>\n\n                <main className=\"flex-1 flex flex-col min-w-0\">\n                    <div className=\"flex-grow flex flex-col bg-background\">\n                         <div className=\"border-b border-border flex items-center bg-surface\">\n                            <button onClick={() => setActiveTab('CODE')} className={`flex items-center gap-2 px-4 py-2 text-sm ${activeTab === 'CODE' ? 'bg-background border-b-2 border-primary text-text-primary' : 'text-text-secondary hover:bg-gray-50'}`}><DocumentTextIcon /> Code</button>\n                            {unitTests && <button onClick={() => setActiveTab('TESTS')} className={`flex items-center gap-2 px-4 py-2 text-sm ${activeTab === 'TESTS' ? 'bg-background border-b-2 border-primary text-text-primary' : 'text-text-secondary hover:bg-gray-50'}`}><BeakerIcon /> Tests</button>}\n                            {commitMessage && <button onClick={() => setActiveTab('COMMIT')} className={`flex items-center gap-2 px-4 py-2 text-sm ${activeTab === 'COMMIT' ? 'bg-background border-b-2 border-primary text-text-primary' : 'text-text-secondary hover:bg-gray-50'}`}><GitBranchIcon /> Commit</button>}\n                        </div>\n                        <div className=\"flex-grow p-2 overflow-auto\">\n                            {isLoading && !generatedFiles.length ? <div className=\"flex justify-center items-center h-full\"><LoadingSpinner/></div> : renderContent()}\n                        </div>\n                    </div>\n                    \n                    <div className=\"flex-shrink-0 p-4 border-t border-border bg-surface\">\n                        <textarea value={prompt} onChange={(e) => setPrompt(e.target.value)} placeholder=\"e.g., A user profile card with an avatar, name, and bio.\" className=\"w-full p-2 bg-background border border-border rounded-md resize-none text-sm h-20\"/>\n                         <button onClick={handleGenerate} disabled={isLoading} className=\"btn-primary mt-2 w-full flex items-center justify-center gap-2 px-4 py-2\">\n                            {isLoading ? <><LoadingSpinner /> Generating...</> : 'Generate Feature'}\n                        </button>\n                         {error && <p className=\"text-red-600 text-xs mt-2 text-center\">{error}</p>}\n                    </div>\n                </main>\n            </div>\n        </div>\n    );\n};"],"names":["AiFeatureBuilder","prompt","setPrompt","useState","generatedFiles","setGeneratedFiles","unitTests","setUnitTests","commitMessage","setCommitMessage","selectedFile","setSelectedFile","isLoading","setIsLoading","error","setError","activeTab","setActiveTab","useEffect","files","getAllFiles","handleGenerate","useCallback","clearAllFiles","resultFiles","generateFeature","file","saveFile","componentFile","f","testStream","generateUnitTestsStream","tests","chunk","diffContext","commitStream","generateCommitMessageStream","commit","err","errorMessage","renderContent","jsx","MarkdownRenderer","jsxs","CpuChipIcon","DocumentTextIcon","BeakerIcon","GitBranchIcon","LoadingSpinner","e","Fragment"],"mappings":"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"}