diff --git a/BBDatastorePlaygroundLogo.svg b/assets/images/BBDatastorePlaygroundLogo.svg similarity index 100% rename from BBDatastorePlaygroundLogo.svg rename to assets/images/BBDatastorePlaygroundLogo.svg diff --git a/package-lock.json b/package-lock.json index 538f860..222812f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,6 +4,7 @@ "requires": true, "packages": { "": { + "name": "bb-datastore-playground", "dependencies": { "@reduxjs/toolkit": "^2.2.5", "@shopify/react-hooks": "^3.1.1", @@ -25,6 +26,8 @@ "react-dom": "^18.2.0", "react-error-boundary": "^4.0.13", "react-redux": "^9.1.2", + "react-router-dom": "^6.23.1", + "react-router-typesafe-routes": "^1.2.2", "react-use-comlink": "^2.0.1", "sass-rem": "^4.0.0", "swr": "^2.2.5", @@ -2700,6 +2703,14 @@ } } }, + "node_modules/@remix-run/router": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.16.1.tgz", + "integrity": "sha512-es2g3dq6Nb07iFxGk5GuHN20RwBZOsuDQN7izWIisUcv9r+d2C5jQxqmgkdebXgReWfiyUabcki6Fg77mSNrig==", + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@restart/hooks": { "version": "0.4.16", "resolved": "https://registry.npmjs.org/@restart/hooks/-/hooks-0.4.16.tgz", @@ -12163,6 +12174,65 @@ } } }, + "node_modules/react-router": { + "version": "6.23.1", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.23.1.tgz", + "integrity": "sha512-fzcOaRF69uvqbbM7OhvQyBTFDVrrGlsFdS3AL+1KfIBtGETibHzi3FkoTRyiDJnWNc2VxrfvR+657ROHjaNjqQ==", + "dependencies": { + "@remix-run/router": "1.16.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8" + } + }, + "node_modules/react-router-dom": { + "version": "6.23.1", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.23.1.tgz", + "integrity": "sha512-utP+K+aSTtEdbWpC+4gxhdlPFwuEfDKq8ZrPFU65bbRJY+l706qjR7yaidBpo3MSeA/fzwbXWbKBI6ftOnP3OQ==", + "dependencies": { + "@remix-run/router": "1.16.1", + "react-router": "6.23.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8", + "react-dom": ">=16.8" + } + }, + "node_modules/react-router-typesafe-routes": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/react-router-typesafe-routes/-/react-router-typesafe-routes-1.2.2.tgz", + "integrity": "sha512-aUTUO0XzEhevQTNACv82SJVRbUMnGCrQIecRwKWLRNt2oKXs01kW4nIJbRV8xwAvv9PR4WKM2Iifd84DiOr73w==", + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "react": ">=16.8", + "react-router-dom": "^6.7.0", + "react-router-native": "^6.7.0", + "yup": "^1.0.0", + "zod": "^3.0.0" + }, + "peerDependenciesMeta": { + "react-router-dom": { + "optional": true + }, + "react-router-native": { + "optional": true + }, + "yup": { + "optional": true + }, + "zod": { + "optional": true + } + } + }, "node_modules/react-transition-group": { "version": "4.4.5", "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", diff --git a/package.json b/package.json index 9f0e9d4..867d9b2 100644 --- a/package.json +++ b/package.json @@ -89,6 +89,8 @@ "react-dom": "^18.2.0", "react-error-boundary": "^4.0.13", "react-redux": "^9.1.2", + "react-router-dom": "^6.23.1", + "react-router-typesafe-routes": "^1.2.2", "react-use-comlink": "^2.0.1", "sass-rem": "^4.0.0", "swr": "^2.2.5", diff --git a/src/main/api/authSlice.ts b/src/main/api/authSlice.ts new file mode 100644 index 0000000..6852640 --- /dev/null +++ b/src/main/api/authSlice.ts @@ -0,0 +1,31 @@ +import { createSlice } from '@reduxjs/toolkit' +import type { PayloadAction } from '@reduxjs/toolkit' +import {User} from "./services/auth"; +import {RootState} from "./store"; + +type AuthState = { + user: User | null + token: string | null +} + +const slice = createSlice({ + name: 'auth', + initialState: { user: null, token: null } as AuthState, + reducers: { + setCredentials: ( + state, + { + payload: { user, token }, + }: PayloadAction<{ user: User; token: string }>, + ) => { + state.user = user + state.token = token + }, + }, +}) + +export const { setCredentials } = slice.actions + +export default slice.reducer + +export const selectCurrentUser = (state: RootState) => state.auth.user diff --git a/src/main/api/services/auth.ts b/src/main/api/services/auth.ts new file mode 100644 index 0000000..beb2545 --- /dev/null +++ b/src/main/api/services/auth.ts @@ -0,0 +1,45 @@ +import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react' +import { RootState } from '../store' + +export interface User { + first_name: string + last_name: string +} + +export interface UserResponse { + user: User + token: string +} + +export interface LoginRequest { + username: string + password: string +} + +export const api = createApi({ + baseQuery: fetchBaseQuery({ + baseUrl: '/', + prepareHeaders: (headers, { getState }) => { + // By default, if we have a token in the store, let's use that for authenticated requests + const token = (getState() as RootState).auth.token + if (token) { + headers.set('authorization', `Bearer ${token}`) + } + return headers + }, + }), + endpoints: (builder) => ({ + login: builder.mutation({ + query: (credentials) => ({ + url: 'login', + method: 'POST', + body: credentials, + }), + }), + protected: builder.mutation<{ message: string }, void>({ + query: () => 'protected', + }), + }), +}) + +export const { useLoginMutation, useProtectedMutation } = api diff --git a/src/main/api/store.ts b/src/main/api/store.ts index 7a9e838..cd6af38 100644 --- a/src/main/api/store.ts +++ b/src/main/api/store.ts @@ -2,10 +2,12 @@ import {configureStore} from '@reduxjs/toolkit'; import workerReducer from './webWorkerApiSlice'; +import authSlice from "./authSlice"; const store = configureStore({ reducer: { worker: workerReducer, + auth: authSlice, }, }); diff --git a/src/main/api/webWorkerApiSlice.ts b/src/main/api/webWorkerApiSlice.ts index b06ff7f..69b611b 100644 --- a/src/main/api/webWorkerApiSlice.ts +++ b/src/main/api/webWorkerApiSlice.ts @@ -20,5 +20,5 @@ const workerSlice = createSlice({ }, }); -export const {setWorker} = workerSlice.actions; +export const {setWorker: setWorkerReducer} = workerSlice.actions; export default workerSlice.reducer; diff --git a/src/main/components/App.tsx b/src/main/components/App.tsx index e00a038..b5661ab 100644 --- a/src/main/components/App.tsx +++ b/src/main/components/App.tsx @@ -8,6 +8,8 @@ import {MyWorker} from "../../pyodide-worker/worker"; import * as comlink from "comlink"; import {Remote} from "comlink"; +import {setWorkerReducer} from "../api/webWorkerApiSlice"; +import {useDispatch} from "react-redux"; const w = new Worker(new URL("../../pyodide-worker/worker.ts", import.meta.url)); @@ -28,17 +30,19 @@ export const App: React.FC = () => { } }, []) + const dispatch = useDispatch(); + useEffect(() => { (async () => { if (worker) { await worker.test(); + //dispatch(setWorkerReducer(worker)); } })(); - }, [worker]) + }, [dispatch, worker]) return (
- diff --git a/src/main/components/MainNavbar.tsx b/src/main/components/MainNavbar.tsx index 8e7017b..decde7d 100644 --- a/src/main/components/MainNavbar.tsx +++ b/src/main/components/MainNavbar.tsx @@ -1,19 +1,59 @@ import React from "react"; import {Container, Navbar} from "react-bootstrap"; +import {useLoginMutation} from "../api/services/auth"; +import {setCredentials} from "../api/authSlice"; +import {useDispatch} from "react-redux"; +import {Link} from "react-router-dom"; export const MainNavbar: React.FC = () => { + const [login, { isLoading }] = useLoginMutation() + const dispatch = useDispatch() + return ( - - + + {' '} BB Datastore Playground +
+ + about + + +
); diff --git a/src/main/components/statusPanel/index.tsx b/src/main/components/statusPanel/index.tsx index ee64c17..0b4dbb0 100644 --- a/src/main/components/statusPanel/index.tsx +++ b/src/main/components/statusPanel/index.tsx @@ -3,6 +3,8 @@ import {useSelector} from "react-redux"; import {RootState} from "../../api/store"; import {useImmer} from "use-immer"; +import * as comlink from "comlink"; + const wat = (str: string) => { console.error(str); } @@ -15,10 +17,8 @@ export const StatusPanel: React.FC = () => { (async () => { if (worker) { console.error("INSTALLLLLLING"); - // await worker.setProgressCallback((str) => { - // console.log(`>>>>> ${str}`) - // }); - // console.error("installed"); + await worker.setProgressCallback(comlink.proxy(wat)); + console.error("installed"); await worker.runPython("print(1 + 2)", new URL("../../../../assets/bitbake-2.8.0.zip", import.meta.url).toString()); console.error("ran python"); } diff --git a/src/main/index.tsx b/src/main/index.tsx index d2b09e2..3ee7674 100644 --- a/src/main/index.tsx +++ b/src/main/index.tsx @@ -5,6 +5,28 @@ import {App} from "./components/App"; import React, {StrictMode} from "react"; import store from "./api/store"; import {Provider} from "react-redux"; +import {BrowserRouter as Router, Routes, Route, createBrowserRouter, Outlet, RouterProvider} from 'react-router-dom'; +import {MainNavbar} from "./components/MainNavbar"; + +const Root: React.FC = () => { + return(
+ + +
); +} + +const router = createBrowserRouter([ + { + element: , + children: [ + { + path: "/", + element: , + }, + ], + }, +]); + const container = document.getElementById("root"); @@ -12,7 +34,7 @@ const root = createRoot(container!); root.render( - + ); \ No newline at end of file diff --git a/src/pyodide-worker/worker.ts b/src/pyodide-worker/worker.ts index fdf47e5..44caab1 100644 --- a/src/pyodide-worker/worker.ts +++ b/src/pyodide-worker/worker.ts @@ -43,6 +43,7 @@ export class MyWorker { async test() { console.log("OK"); + await printAll("callback!"); } async runPython(python: string, u: string) { diff --git a/webpack.config.ts b/webpack.config.ts index db7aa99..3bf3cb5 100644 --- a/webpack.config.ts +++ b/webpack.config.ts @@ -139,6 +139,8 @@ module.exports = (env: any, argv: any) => { externals: { pyodide: 'pyodide' }, - + devServer: { + historyApiFallback: true, + } } }