diff --git a/package.json b/package.json index 1ff9549..2484762 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "@fortawesome/react-fontawesome": "^0.2.0", "@mui/icons-material": "^5.11.16", "@mui/material": "^5.13.4", + "axios": "^1.4.0", "electron": "^25.1.0", "electron-is-dev": "^2.0.0", "react": "^18.2.0", diff --git a/public/electron.js b/public/electron.js index 9619a18..6bc0e9e 100644 --- a/public/electron.js +++ b/public/electron.js @@ -1,5 +1,5 @@ const path = require('path'); -const { app, BrowserWindow } = require('electron'); +const { app, BrowserWindow, dialog, ipcMain } = require('electron'); const isDev = require('electron-is-dev'); function createWindow() { @@ -8,6 +8,7 @@ function createWindow() { height: 600, webPreferences: { nodeIntegration: true, + contextIsolation: false }, icon: './icons/icon.png', show: false, @@ -27,6 +28,20 @@ function createWindow() { mainWindow.on('page-title-updated', function (e) { e.preventDefault(); }); + + ipcMain.on('openFolder', (event, arg) => { + dialog + .showOpenDialog({ + properties: ['openDirectory'], + }) + .then((result) => { + event.reply('folderData', result.filePaths); + }) + .catch((error) => { + console.error(error); + event.reply('folderData', []); + }); + }); } app.whenReady().then(createWindow); @@ -41,4 +56,4 @@ app.on('activate', () => { if (BrowserWindow.getAllWindows().length === 0) { createWindow(); } -}); +}); \ No newline at end of file diff --git a/src/App.css b/src/App.css index b027199..efcd29b 100644 --- a/src/App.css +++ b/src/App.css @@ -18,5 +18,5 @@ padding: 20px; align-items: center; display: 'grid'; - grid-template-columns: 'repeat(2, 1fr)'; + grid-template-columns: repeat(2, 1fr); } diff --git a/src/FunctionalityCard.js b/src/FunctionalityCard.js index c71a0c1..14ae21b 100644 --- a/src/FunctionalityCard.js +++ b/src/FunctionalityCard.js @@ -2,12 +2,24 @@ import * as React from 'react'; import Card from '@mui/material/Card'; import CardActions from '@mui/material/CardActions'; import CardContent from '@mui/material/CardContent'; -import Button from '@mui/material/Button'; import Typography from '@mui/material/Typography'; +import InitModal from './InitModal.js'; +import PluginsModal from './PluginsModal.js'; + +function cardChooser(command) { + switch (command) { + case 'init': + return + case 'plugins': + return + default: + return null + } +} export default function FunctionalityCard({ command, description }) { return ( - + {description} @@ -17,7 +29,8 @@ export default function FunctionalityCard({ command, description }) { - Get started + {/*Get started*/} + {cardChooser(command)} ); diff --git a/src/InitModal.js b/src/InitModal.js new file mode 100644 index 0000000..a22b945 --- /dev/null +++ b/src/InitModal.js @@ -0,0 +1,182 @@ +import * as React from 'react'; +import Box from '@mui/material/Box'; +import Button from '@mui/material/Button'; +import Typography from '@mui/material/Typography'; +import Modal from '@mui/material/Modal'; +import InputLabel from '@mui/material/InputLabel'; +import MenuItem from '@mui/material/MenuItem'; +import FormControl from '@mui/material/FormControl'; +import Select from '@mui/material/Select'; +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 './modalStyles.css'; +const { ipcRenderer } = window.require('electron') + +// eslint-disable-next-line no-unused-vars +const style = { + position: 'absolute', + top: '50%', + left: '50%', + transform: 'translate(-50%, -50%)', + width: 400, + bgcolor: 'background.paper', + border: '2px solid #FFF', + boxShadow: 24, + padding: '20px', + color: 'white', +}; + +export default function InitModal() { + const [open, setOpen] = React.useState(false); + const handleOpen = () => setOpen(true); + const handleClose = () => setOpen(false); + + const [chosenTemplate, setChosenTemplate] = React.useState(''); + const handleTemplateChange = (event) => { + setChosenTemplate(event.target.value); + }; + + const [installPackages, setInstallPackages] = React.useState(true); + const handlePackagesChange = (event) => { + setInstallPackages(event.target.checked); + }; + + const [chosenPackageManager, setChosenPackageManager] = React.useState(''); + const handlePackageManagerChange = (event) => { + setChosenPackageManager(event.target.value); + }; + + const [templates, setTemplates] = React.useState([]); + React.useEffect(() => { + fetch('https://raw.githubusercontent.com/sern-handler/create-bot/main/metadata/templateChoices.json') + .then((res) => res.json()) + .then((data) => { + setTemplates(data); + }) + .catch((err) => { + console.log(err.message); + }); + }, []); + + if (templates.length === 0) { + setTemplates([{ title: "Couldn't fetch templates! Please do CTRL+R", value: 'error' }]); + } + + const [selectedPath, setSelectedPath] = React.useState(''); + + const handleChooseDirButton = () => { + ipcRenderer.send('openFolder'); + }; + + React.useEffect(() => { + ipcRenderer.on('folderData', handleFolderData); + + return () => { + ipcRenderer.removeListener('folderData', handleFolderData); + }; + }, []); + + const handleFolderData = (event, paths) => { + const selectedPath = paths && paths.length > 0 ? paths[0] : ''; + setSelectedPath(selectedPath); + }; + + return ( + + Open modal + + + + ~$ sern init + + + + + + Select template + + + {templates.map((template) => ( + + {template.title} + + ))} + + + + + + + } + fullWidth + label="Install packages while you're at it" + /> + + + + Select package manager + + + npm + yarn + pnpm + + + + + + Select directory + + {/* + Selected directory: {selectedPath} + */} + + + + + ); +} diff --git a/src/PluginsModal.js b/src/PluginsModal.js new file mode 100644 index 0000000..51ee978 --- /dev/null +++ b/src/PluginsModal.js @@ -0,0 +1,45 @@ +import * as React from 'react'; +import Box from '@mui/material/Box'; +import Button from '@mui/material/Button'; +import Typography from '@mui/material/Typography'; +import Modal from '@mui/material/Modal'; + +/* const style = { + position: 'absolute', + top: '50%', + left: '50%', + transform: 'translate(-50%, -50%)', + width: 400, + bgcolor: 'background.paper', + border: '2px solid #000', + boxShadow: 24, + p: 4, +}; */ + +export default function PluginsModal() { + // eslint-disable-next-line react-hooks/rules-of-hooks + const [open, setOpen] = React.useState(false); + const handleOpen = () => setOpen(true); + const handleClose = () => setOpen(false); + + return ( + + Open modal + + + + Text in a modal + + + Duis mollis, est non commodo luctus, nisi erat porttitor ligula. + + + + + ); +} \ No newline at end of file diff --git a/src/modalStyles.css b/src/modalStyles.css new file mode 100644 index 0000000..b1423a5 --- /dev/null +++ b/src/modalStyles.css @@ -0,0 +1,35 @@ +@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono&display=swap'); + +#modal-modal-title { + text-align: center; + color: #4af626; + font-family: 'JetBrains Mono', 'Courier New', Courier, monospace; + font-weight: bold; + font-size: 2em; + margin-bottom: 40px; +} + +.boxStyle { + /* background-color: 'background.paper'; set in sx property of Box tag */ + transform: translate(-50%, -50%); + position: absolute; + top: 50%; + left: 50%; + width: 74.6vw; + height: 74.6vh; + border: 2px solid #FFF; + box-shadow: 24px; + padding: 40px; + color: white; +} + +.chooseTemplateForm { + display: flex; + flex-direction: column; +} + +.formRow { + display: flex; + gap: 20px; + margin-bottom: 20px; +} \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 4e3ad06..eb2827d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3074,6 +3074,15 @@ axios@^0.27.2: follow-redirects "^1.14.9" form-data "^4.0.0" +axios@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/axios/-/axios-1.4.0.tgz#38a7bf1224cd308de271146038b551d725f0be1f" + integrity sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA== + dependencies: + follow-redirects "^1.15.0" + form-data "^4.0.0" + proxy-from-env "^1.1.0" + axobject-query@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-3.1.1.tgz#3b6e5c6d4e43ca7ba51c5babf99d22a9c68485e1" @@ -5081,7 +5090,7 @@ flora-colossus@^1.0.0: debug "^4.1.1" fs-extra "^7.0.0" -follow-redirects@^1.0.0, follow-redirects@^1.14.9: +follow-redirects@^1.0.0, follow-redirects@^1.14.9, follow-redirects@^1.15.0: version "1.15.2" resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13" integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA== @@ -8206,6 +8215,11 @@ proxy-addr@~2.0.7: forwarded "0.2.0" ipaddr.js "1.9.1" +proxy-from-env@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" + integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== + psl@^1.1.33: version "1.9.0" resolved "https://registry.yarnpkg.com/psl/-/psl-1.9.0.tgz#d0df2a137f00794565fcaf3b2c00cd09f8d5a5a7"