@codewithmehmet/paul-cli
Version:
Intelligent project file scanner and Git change tracker with interactive interface
141 lines (139 loc) • 5.72 kB
JavaScript
import React, { useState, useEffect } from 'react';
import { Box, Text } from 'ink';
import { useInput } from 'ink';
import TextInput from 'ink-text-input';
import { PresetService } from '../services/presetService.js';
import fs from 'fs';
import path from 'path';
const presetService = new PresetService();
export default function PresetManager({
selectedFiles,
onApply,
onBack
}) {
const [presets, setPresets] = useState([]);
const [mode, setMode] = useState('list'); // 'list', 'save', 'delete'
const [pointer, setPointer] = useState(0);
const [presetName, setPresetName] = useState('');
useEffect(() => {
loadPresets();
}, []);
const loadPresets = async () => {
const loaded = await presetService.loadPresets();
setPresets(loaded);
};
const handleSave = async () => {
if (presetName) {
await presetService.savePreset(presetName, selectedFiles);
await loadPresets();
setMode('list');
setPresetName('');
}
};
const handleApply = async preset => {
const validFiles = new Set();
let removedCount = 0;
for (const filePath of preset.selectedFiles) {
// Convertir en chemin absolu si nécessaire
const fullPath = path.isAbsolute(filePath) ? filePath : path.join(process.cwd(), filePath);
// Vérifier si le fichier existe encore
if (fs.existsSync(fullPath)) {
validFiles.add(fullPath);
} else {
removedCount++;
}
}
// Afficher un message si des fichiers ont été supprimés
if (removedCount > 0) {
console.log(`⚠️ ${removedCount} files from preset no longer exist`);
}
onApply(validFiles);
onBack();
};
const handleDelete = async id => {
await presetService.deletePreset(id);
await loadPresets();
setMode('list');
};
useInput((input, key) => {
if (mode === 'list') {
if (key.escape || input === 'q') {
onBack();
} else if (key.upArrow) {
setPointer(Math.max(0, pointer - 1));
} else if (key.downArrow) {
const maxIndex = selectedFiles.size > 0 ? presets.length + 1 : presets.length;
setPointer(Math.min(maxIndex, pointer + 1));
} else if (key.return) {
if (pointer < presets.length) {
handleApply(presets[pointer]);
} else if (pointer === presets.length && selectedFiles.size > 0) {
setMode('save');
} else if (pointer === presets.length + 1) {
setMode('delete');
setPointer(0);
}
}
} else if (mode === 'save') {
if (key.escape) {
setMode('list');
}
} else if (mode === 'delete') {
if (key.escape) {
setMode('list');
} else if (key.upArrow) {
setPointer(Math.max(0, pointer - 1));
} else if (key.downArrow) {
setPointer(Math.min(presets.length - 1, pointer + 1));
} else if (key.return) {
handleDelete(presets[pointer].id);
}
}
});
if (mode === 'save') {
return /*#__PURE__*/React.createElement(Box, {
flexDirection: "column"
}, /*#__PURE__*/React.createElement(Text, {
color: "cyan",
bold: true
}, "\uD83D\uDCBE Save Preset"), /*#__PURE__*/React.createElement(Text, null, " "), /*#__PURE__*/React.createElement(Text, null, "Enter preset name:"), /*#__PURE__*/React.createElement(TextInput, {
value: presetName,
onChange: setPresetName,
onSubmit: handleSave
}), /*#__PURE__*/React.createElement(Text, null, " "), /*#__PURE__*/React.createElement(Text, {
color: "gray"
}, "Press Enter to save, ESC to cancel"));
}
if (mode === 'delete') {
return /*#__PURE__*/React.createElement(Box, {
flexDirection: "column"
}, /*#__PURE__*/React.createElement(Text, {
color: "red",
bold: true
}, "\u274C Delete Preset"), /*#__PURE__*/React.createElement(Text, null, " "), presets.map((preset, i) => /*#__PURE__*/React.createElement(Text, {
key: preset.id,
color: i === pointer ? 'cyan' : 'white'
}, i === pointer ? '▶ ' : ' ', preset.name, " (", preset.selectedFiles.length, " files)")), /*#__PURE__*/React.createElement(Text, null, " "), /*#__PURE__*/React.createElement(Text, {
color: "gray"
}, "Press Enter to delete, ESC to cancel"));
}
return /*#__PURE__*/React.createElement(Box, {
flexDirection: "column"
}, /*#__PURE__*/React.createElement(Text, {
color: "cyan",
bold: true
}, "\uD83D\uDCE6 Preset Manager"), /*#__PURE__*/React.createElement(Text, null, " "), presets.length === 0 && selectedFiles.size === 0 ? /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Text, {
color: "gray"
}, "No presets saved yet."), /*#__PURE__*/React.createElement(Text, {
color: "gray"
}, "Select files first, then press 'p' to save.")) : /*#__PURE__*/React.createElement(React.Fragment, null, presets.map((preset, i) => /*#__PURE__*/React.createElement(Text, {
key: preset.id,
color: i === pointer ? 'cyan' : 'white'
}, i === pointer ? '▶ ' : ' ', "\u2B50 ", preset.name, " (", preset.selectedFiles.length, " files)")), selectedFiles.size > 0 && /*#__PURE__*/React.createElement(Text, {
color: pointer === presets.length ? 'cyan' : 'white'
}, pointer === presets.length ? '▶ ' : ' ', "\uD83D\uDCBE Save current selection"), presets.length > 0 && /*#__PURE__*/React.createElement(Text, {
color: pointer === presets.length + 1 ? 'cyan' : 'white'
}, pointer === presets.length + 1 ? '▶ ' : ' ', "\u274C Delete a preset")), /*#__PURE__*/React.createElement(Text, null, " "), /*#__PURE__*/React.createElement(Text, {
color: "gray"
}, "\u2191\u2193 Navigate | Enter Select | ESC Back"));
}