Skip to content

Commit 0237349

Browse files
committed
feat: add requirements route
1 parent 350b4ba commit 0237349

File tree

10 files changed

+284
-60
lines changed

10 files changed

+284
-60
lines changed

package-lock.json

+40-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
"axios": "^1.4.0",
5151
"electron-squirrel-startup": "^1.0.0",
5252
"react": "^18.2.0",
53-
"react-dom": "^18.2.0"
53+
"react-dom": "^18.2.0",
54+
"react-router-dom": "^6.14.1"
5455
}
5556
}

src/index.ts

+20-17
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
import { app, BrowserWindow, ipcMain, IpcMainEvent } from 'electron';
21
import { exec } from 'child_process';
2+
import { app, BrowserWindow, ipcMain } from 'electron';
3+
import { promisify } from 'node:util';
34

45
// This allows TypeScript to pick up the magic constants that's auto-generated by Forge's Webpack
56
// plugin that tells the Electron app where to look for the Webpack-bundled app code (depending on
@@ -33,7 +34,7 @@ const createWindow = (): void => {
3334
// initialization and is ready to create browser windows.
3435
// Some APIs can only be used after this event occurs.
3536
app.on('ready', () => {
36-
ipcMain.on('set-title', handleSetTitle);
37+
ipcMain.handle('get-requirements', getRequirements);
3738

3839
return createWindow();
3940
});
@@ -57,19 +58,21 @@ app.on('activate', () => {
5758

5859
// In this file you can include the rest of your app's specific main process
5960
// code. You can also put them in separate files and import them here.
60-
function handleSetTitle(event: IpcMainEvent, title: string) {
61-
exec('node -v', (error, stdout, stderr) => {
62-
if (error) {
63-
console.log(`error: ${error.message}`);
64-
return;
65-
}
66-
if (stderr) {
67-
console.log(`stderr: ${stderr}`);
68-
return;
69-
}
70-
console.log(`stdout: ${stdout}`);
71-
const webContents = event.sender;
72-
const win = BrowserWindow.fromWebContents(webContents);
73-
win.setTitle(stdout);
74-
});
61+
const requirements = [
62+
'node -v',
63+
'npm -v',
64+
'mvn --version',
65+
'java -version',
66+
'git --version',
67+
];
68+
const execPromise = promisify(exec);
69+
70+
async function getRequirements(): Promise<
71+
{ stdout: string; stderr: string }[]
72+
> {
73+
return Promise.all(
74+
requirements.map(requirement => {
75+
return execPromise(requirement);
76+
})
77+
);
7578
}

src/preload.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { contextBridge, ipcRenderer } from 'electron';
22

33
contextBridge.exposeInMainWorld('electronAPI', {
4-
setTitle: (title: string) => ipcRenderer.send('set-title', title),
4+
getRequirements: () => ipcRenderer.invoke('get-requirements'),
55
});

src/ui/app.tsx

+31-1
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,40 @@
1+
import React from 'react';
12
import { createRoot } from 'react-dom/client';
3+
import { createHashRouter, RouterProvider } from 'react-router-dom';
4+
import Requirements from './modules/requirements/requirements';
25
import { TipManager } from './tip-manager';
6+
import Overview from './modules/overview/main';
7+
8+
const router = createHashRouter([
9+
{
10+
path: '/',
11+
element: <TipManager />,
12+
errorElement: (
13+
<div>
14+
<a href="/main_window">Home</a>
15+
</div>
16+
),
17+
children: [
18+
{
19+
path: 'requirements',
20+
element: <Requirements />,
21+
},
22+
{
23+
index: true,
24+
element: <Overview />,
25+
}
26+
],
27+
},
28+
]);
329

430
function render() {
531
const container = document.getElementById('app');
632
const root = createRoot(container);
7-
root.render(<TipManager />);
33+
root.render(
34+
<React.StrictMode>
35+
<RouterProvider router={router} />
36+
</React.StrictMode>
37+
);
838
}
939

1040
render();

src/ui/electron-api/base.ts

+6-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
declare global {
22
interface Window {
3-
electronAPI: any;
3+
electronAPI: ElectronAPI;
44
}
55
}
66

7+
export interface ElectronAPI {
8+
getRequirements: () => Promise<{ stdout: string; stderr: string }[]>;
9+
}
10+
711
export class BaseAPI {
8-
private _base: any;
12+
private _base: ElectronAPI;
913

1014
get base() {
1115
return this._base;

src/ui/electron-api/common.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import { BaseAPI } from "./base";
1+
import { BaseAPI } from './base';
22

33
export class CommonAPI extends BaseAPI {
4-
setTitle(title: string) {
5-
this.base.setTitle(title);
4+
async getRequirements(): Promise<{ stdout: string; stderr: string }[]> {
5+
return this.base.getRequirements();
66
}
77
}

src/ui/modules/overview/main.tsx

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import Typography from '@mui/material/Typography';
2+
3+
export default function Overview() {
4+
return (
5+
<Typography paragraph>
6+
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
7+
tempor incididunt ut labore et dolore magna aliqua. Rhoncus dolor purus
8+
non enim praesent elementum facilisis leo vel. Risus at ultrices mi tempus
9+
imperdiet. Semper risus in hendrerit gravida rutrum quisque non tellus.
10+
Convallis convallis tellus id interdum velit laoreet id donec ultrices.
11+
Odio morbi quis commodo odio aenean sed adipiscing. Amet nisl suscipit
12+
adipiscing bibendum est ultricies integer quis. Cursus euismod quis
13+
viverra nibh cras. Metus vulputate eu scelerisque felis imperdiet proin
14+
fermentum leo. Mauris commodo quis imperdiet massa tincidunt. Cras
15+
tincidunt lobortis feugiat vivamus at augue. At augue eget arcu dictum
16+
varius duis at consectetur lorem. Velit sed ullamcorper morbi tincidunt.
17+
Lorem donec massa sapien faucibus et molestie ac.
18+
</Typography>
19+
);
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import Button from '@mui/material/Button';
2+
import { useState } from 'react';
3+
import { CommonAPI } from '../../electron-api/common';
4+
5+
export default function Requirements() {
6+
const getRequirements = async () => {
7+
const requirements = await new CommonAPI().getRequirements();
8+
setRequirements(requirements.map(requirement => requirement.stdout));
9+
};
10+
11+
const [requirements, setRequirements] = useState<string[]>([]);
12+
13+
return (
14+
<div>
15+
<h1>Requirements</h1>
16+
<Button variant="contained" onClick={getRequirements}>
17+
Check
18+
</Button>
19+
<ul>
20+
{requirements.map((requirement, index) => (
21+
<li key={index}>{requirement}</li>
22+
))}
23+
</ul>
24+
</div>
25+
);
26+
}

0 commit comments

Comments
 (0)