Newer
Older
cortex-hub / frontend / src / features / skills / components / SkillEditor.js
import React, { useState, useEffect } from 'react';

export default function SkillEditor({ activeFile, content, onChange, onSave, isSaving }) {
    const [localContent, setLocalContent] = useState(content || '');

    useEffect(() => {
        setLocalContent(content || '');
    }, [content, activeFile]);

    const handleKeyDown = (e) => {
        if ((e.ctrlKey || e.metaKey) && e.key === 's') {
            e.preventDefault();
            onSave(localContent);
            return;
        }
        
        // Handle tab indentation
        if (e.key === 'Tab' && !e.shiftKey) {
            e.preventDefault();
            const start = e.target.selectionStart;
            const end = e.target.selectionEnd;
            const newContent = localContent.substring(0, start) + "    " + localContent.substring(end);
            setLocalContent(newContent);
            onChange(newContent);
            // Move cursor
            setTimeout(() => {
                e.target.selectionStart = e.target.selectionEnd = start + 4;
            }, 0);
        }
    };

    const handleChange = (e) => {
        setLocalContent(e.target.value);
        onChange(e.target.value);
    };

    if (!activeFile) {
        return (
            <div className="flex-grow flex items-center justify-center bg-gray-50 dark:bg-gray-900 border-l border-gray-200 dark:border-gray-700 h-full">
                <p className="text-sm text-gray-400 italic font-medium">Select a file from the tree to edit</p>
            </div>
        );
    }

    return (
        <div className="flex-grow flex flex-col h-full bg-white dark:bg-[#0d1117]">
            <div className="flex items-center justify-between px-6 py-3 border-b border-gray-200 dark:border-gray-800 bg-gray-50/50 dark:bg-gray-900/50">
                <div className="flex items-center gap-2">
                    <span className="text-xs font-mono font-bold text-gray-700 dark:text-gray-300">{activeFile}</span>
                    {localContent !== content && <span className="w-2 h-2 rounded-full bg-yellow-400 animate-pulse"></span>}
                </div>
                <button 
                    onClick={() => onSave(localContent)}
                    disabled={isSaving || localContent === content}
                    className={`px-4 py-1.5 text-[10px] font-black uppercase tracking-widest rounded-md transition-all ${localContent !== content ? 'bg-indigo-600 text-white hover:bg-indigo-700 shadow-md active:scale-95' : 'bg-gray-200 dark:bg-gray-800 text-gray-400 cursor-not-allowed'}`}
                >
                    {isSaving ? 'Saving...' : 'Save (Ctrl+S)'}
                </button>
            </div>
            <textarea
                value={localContent}
                onChange={handleChange}
                onKeyDown={handleKeyDown}
                className="flex-grow w-full p-6 text-[13px] font-mono bg-transparent text-gray-800 dark:text-gray-300 focus:outline-none resize-none custom-scrollbar leading-relaxed"
                spellCheck={false}
                placeholder="Type your code or markdown here..."
            />
        </div>
    );
}