diff --git a/.prettierrc b/.prettierrc index 964f480..bca636c 100644 --- a/.prettierrc +++ b/.prettierrc @@ -1,5 +1,5 @@ { - "tabWidth": 4, + "tabWidth": 2, "useTabs": true, "singleQuote": true } \ No newline at end of file diff --git a/package.json b/package.json index 2484762..58c5568 100644 --- a/package.json +++ b/package.json @@ -13,8 +13,10 @@ "@fortawesome/free-solid-svg-icons": "^6.4.0", "@fortawesome/react-fontawesome": "^0.2.0", "@mui/icons-material": "^5.11.16", + "@mui/lab": "^5.0.0-alpha.134", "@mui/material": "^5.13.4", "axios": "^1.4.0", + "colorette": "^2.0.20", "electron": "^25.1.0", "electron-is-dev": "^2.0.0", "react": "^18.2.0", diff --git a/public/ascii.txt b/public/ascii.txt new file mode 100644 index 0000000..bad7e24 --- /dev/null +++ b/public/ascii.txt @@ -0,0 +1,16 @@ + .:-=-:. + .:=+++++++++=-. + :-=+++++++++++++++++=-: +=++++++++++++++++++++=:. +=+++++++++++++++=-: +=++++++++++++-. ###### ######## ######## ## ## ###### ## ## #### +=++++++++++++*+=:. ## ## ## ## ## ### ## ## ## ## ## ## +=++++++++++++******=-. ## ## ## ## #### ## ## ## ## ## +:=+++++++++++**********+- ###### ###### ######## ## ## ## ## #### ## ## ## + .:-+++++++********###* ## ## ## ## ## #### ## ## ## ## ## + :-=++***########* ## ## ## ## ## ## ### ## ## ## ## ## + .-*###########* ###### ######## ## ## ## ## ###### ####### #### + :=+###############* + .-=*###################* +.:=*#################*=-. + :=+#########+=: diff --git a/public/electron.js b/public/electron.js index 6bc0e9e..2ecedd4 100644 --- a/public/electron.js +++ b/public/electron.js @@ -1,6 +1,9 @@ const path = require('path'); const { app, BrowserWindow, dialog, ipcMain } = require('electron'); const isDev = require('electron-is-dev'); +const fs = require('fs'); +const colorette = require('colorette') +const { spawn } = require('node:child_process') function createWindow() { const mainWindow = new BrowserWindow({ @@ -41,7 +44,62 @@ function createWindow() { console.error(error); event.reply('folderData', []); }); - }); + }); + + ipcMain.on('submitForm', async (event, data) => { + // Process the submitted data here + console.log(`${colorette.green('✓')} Received sern init submit form data:`) + console.log(data); + console.log(`${colorette.cyan('🛈')} Current OS: ${currentOS}`) + + let packageManagerCommand + switch (data.chosenPackageManager) { + case 'npm': + packageManagerCommand = `npm create @sern/bot@latest -- --template=${data.chosenTemplate} --name="${data.projectName}" --install=npm` + break; + case 'yarn': + packageManagerCommand = `npm create @sern/bot@latest -- --template=${data.chosenTemplate} --name="${data.projectName}" --install=yarn` + break; + case 'pnpm': + packageManagerCommand = `npm create @sern/bot@latest -- --template=${data.chosenTemplate} --name="${data.projectName}" --install=pnpm` + break; + default: + packageManagerCommand = `npm create @sern/bot@latest -- --template=${data.chosenTemplate} --name="${data.projectName}"` + break; + } + let commandToRun + switch (currentOS) { + case 'linux': + commandToRun = `cd ${data.selectedPath};${packageManagerCommand}` + break; + case 'windows': + commandToRun = `cd /D ${data.selectedPath};${packageManagerCommand}` + break; + case 'macOS': + commandToRun = `cd ${data.selectedPath};${packageManagerCommand}` + break; + default: + // defaulting for linux (most probable command syntax) + commandToRun = `cd ${data.selectedPath};${packageManagerCommand}` + break; + } + + console.log(`${colorette.cyan('🛈')} About to execute command: ${commandToRun}`) + const cmd = spawn(commandToRun, { shell: true }) + + cmd.stdout.on('data', (data) => { + console.log(`${colorette.cyan('🛈')} Command stdout: ${data}`); + }); + + cmd.stderr.on('data', (data) => { + console.error(`${colorette.red('×')} Command stderr: ${data}`); + }); + + cmd.on('close', (code) => { + console.log(`${colorette.cyan('🛈')} Command exited with status code ${code}. Now notifying frontend...`); + event.reply('submitForm') + }); + }); } app.whenReady().then(createWindow); @@ -56,4 +114,23 @@ app.on('activate', () => { if (BrowserWindow.getAllWindows().length === 0) { createWindow(); } -}); \ No newline at end of file +}); + +let currentOS +switch (process.platform) { + case 'linux': + currentOS = 'linux' + break; + case 'win32': + currentOS = 'windows' + break; + case 'darwin': + currentOS = 'macOS' + break; + default: + // defaulting for linux (most probable command syntax) + currentOS = 'linux' + break; +} + +console.log(fs.readFileSync(__dirname + '/ascii.txt', 'utf-8')) \ No newline at end of file diff --git a/src/InitModal.js b/src/InitModal.js index a22b945..a9cdb42 100644 --- a/src/InitModal.js +++ b/src/InitModal.js @@ -11,9 +11,9 @@ import TextField from '@mui/material/TextField'; import Checkbox from '@mui/material/Checkbox'; import FormGroup from '@mui/material/FormGroup'; import FormControlLabel from '@mui/material/FormControlLabel'; -import CardActions from '@mui/material/CardActions'; +import Alert from '@mui/material/Alert'; import './modalStyles.css'; -const { ipcRenderer } = window.require('electron') +const { ipcRenderer } = window.require('electron'); // eslint-disable-next-line no-unused-vars const style = { @@ -71,6 +71,11 @@ export default function InitModal() { ipcRenderer.send('openFolder'); }; + const [projectName, setProjectName] = React.useState(''); + const handleProjectNameChange = (event) => { + setProjectName(event.target.value); + }; + React.useEffect(() => { ipcRenderer.on('folderData', handleFolderData); @@ -84,99 +89,155 @@ export default function InitModal() { setSelectedPath(selectedPath); }; + const [loading, setLoading] = React.useState(false); + + const isFormValid = () => { + return projectName !== '' && selectedPath !== ''; + }; + + const handleSubmit = () => { + if (!isFormValid()) { + return; + } + + const data = { + projectName, + chosenTemplate, + installPackages, + chosenPackageManager, + selectedPath, + }; + + setLoading(true); + + ipcRenderer.send('submitForm', data); + + ipcRenderer.on('submitForm', () => { + setLoading(false); + handleClose(); + ipcRenderer.removeAllListeners('submitForm'); // Remove the listener to avoid memory leaks + }); + } + return ( -