diff --git a/web/src/components/IdeConsole/IdeConsole.js b/web/src/components/IdeConsole/IdeConsole.js
new file mode 100644
index 0000000..a373156
--- /dev/null
+++ b/web/src/components/IdeConsole/IdeConsole.js
@@ -0,0 +1,23 @@
+import { useContext } from 'react'
+import { IdeContext } from 'src/components/IdeToolbarNew'
+
+const IdeConsole = () => {
+ const { state } = useContext(IdeContext)
+ return (
+
+
hi I'm console
+
+ {state.consoleMessages?.map(({ type, message }, index) => (
+
+ -> {message}
+
+ ))}
+
+
+ )
+}
+
+export default IdeConsole
diff --git a/web/src/components/IdeContainer/IdeContainer.js b/web/src/components/IdeContainer/IdeContainer.js
new file mode 100644
index 0000000..8e57fa4
--- /dev/null
+++ b/web/src/components/IdeContainer/IdeContainer.js
@@ -0,0 +1,18 @@
+import IdeEditor from 'src/components/IdeEditor'
+import IdeViewer from 'src/components/IdeViewer'
+import IdeConsole from 'src/components/IdeConsole'
+
+const IdeContainer = () => {
+ return (
+
+
hi I'm IDE container
+
+
+
+
+
+
+ )
+}
+
+export default IdeContainer
diff --git a/web/src/components/IdeEditor/IdeEditor.js b/web/src/components/IdeEditor/IdeEditor.js
new file mode 100644
index 0000000..1b6658f
--- /dev/null
+++ b/web/src/components/IdeEditor/IdeEditor.js
@@ -0,0 +1,29 @@
+import { useContext } from 'react'
+import { IdeContext } from 'src/components/IdeToolbarNew'
+
+const IdeEditor = () => {
+ const { state, dispatch } = useContext(IdeContext)
+ return (
+
+
hi I'm editor
+
code:
+
+ dispatch({ type: 'updateCode', payload: target.value })
+ }
+ />
+
+
+ )
+}
+
+export default IdeEditor
diff --git a/web/src/components/IdeToolbarNew/IdeToolbarNew.js b/web/src/components/IdeToolbarNew/IdeToolbarNew.js
new file mode 100644
index 0000000..9aee054
--- /dev/null
+++ b/web/src/components/IdeToolbarNew/IdeToolbarNew.js
@@ -0,0 +1,19 @@
+import IdeContainer from 'src/components/IdeContainer'
+import { createContext } from 'react'
+import { useIdeState } from 'src/helpers/hooks/useIdeState'
+
+export const IdeContext = createContext()
+
+const IdeToolbarNew = () => {
+ const [state, dispatch] = useIdeState()
+ return (
+
+
+
+ )
+}
+
+export default IdeToolbarNew
diff --git a/web/src/components/IdeViewer/IdeViewer.js b/web/src/components/IdeViewer/IdeViewer.js
new file mode 100644
index 0000000..ae0cb3c
--- /dev/null
+++ b/web/src/components/IdeViewer/IdeViewer.js
@@ -0,0 +1,18 @@
+import { useContext } from 'react'
+import { IdeContext } from 'src/components/IdeToolbarNew'
+
+const IdeViewer = () => {
+ const { state } = useContext(IdeContext)
+ return (
+
+
hi I'm viewer
+
+ I should be showing an{' '}
+ {state.objectData?.type}{' '}
+ right now
+
+
+ )
+}
+
+export default IdeViewer
diff --git a/web/src/helpers/hooks/useIdeState.js b/web/src/helpers/hooks/useIdeState.js
new file mode 100644
index 0000000..8a34956
--- /dev/null
+++ b/web/src/helpers/hooks/useIdeState.js
@@ -0,0 +1,69 @@
+import { useReducer } from 'react'
+import { renderOpenScad } from 'src/helpers/openScadController'
+
+export const useIdeState = () => {
+ const initialState = {
+ ideType: 'openscad',
+ consoleMessages: [
+ { type: 'error', message: 'line 15 is being very naughty' },
+ { type: 'message', message: '5 bodies produced' },
+ ],
+ code: 'cubie(60);',
+ objectData: {
+ type: 'stl',
+ data: 'some binary',
+ },
+ }
+ const reducer = (state, { type, payload }) => {
+ switch (type) {
+ case 'updateCode':
+ return { ...state, code: payload }
+ case 'healthyRender':
+ return {
+ ...state,
+ objectData: {
+ type: payload.objectData?.type,
+ data: payload.objectData?.data,
+ },
+ consoleMessages: payload.message
+ ? [...state.consoleMessages, payload.message]
+ : payload.message,
+ }
+ case 'errorRender':
+ return {
+ ...state,
+ consoleMessages: payload.message
+ ? [...state.consoleMessages, payload.message]
+ : payload.message,
+ }
+ }
+ }
+
+ function dispatchMiddleware(dispatch) {
+ return ({ type, payload }) => {
+ switch (type) {
+ case 'render':
+ renderOpenScad({ code: payload.code })
+ .then(({ objectData, message }) =>
+ dispatch({
+ type: 'healthyRender',
+ payload: { objectData, message },
+ })
+ )
+ .catch(({ message }) =>
+ dispatch({
+ type: 'errorRender',
+ payload: { message },
+ })
+ )
+ break
+
+ default:
+ return dispatch({ type, payload })
+ }
+ }
+ }
+
+ const [state, dispatch] = useReducer(reducer, initialState)
+ return [state, dispatchMiddleware(dispatch)]
+}
diff --git a/web/src/helpers/openScadController.js b/web/src/helpers/openScadController.js
new file mode 100644
index 0000000..3727a1c
--- /dev/null
+++ b/web/src/helpers/openScadController.js
@@ -0,0 +1,26 @@
+export const renderOpenScad = async ({ code, settings }) => {
+ return new Promise((resolve, reject) => {
+ setTimeout(() => {
+ const shouldReject = Math.random() < 0.7
+ if (shouldReject) {
+ resolve({
+ objectData: {
+ type: Math.random() > 0.6 ? 'stl' : 'jpg',
+ data: 'some binary',
+ },
+ message: {
+ type: 'message',
+ message: `bodies rendered by: ${code}`,
+ },
+ })
+ } else {
+ reject({
+ message: {
+ type: 'error',
+ message: 'unable to parse line: x',
+ },
+ })
+ }
+ }, 700)
+ })
+}
diff --git a/web/src/pages/HomePage/HomePage.js b/web/src/pages/HomePage/HomePage.js
index e853fe8..97f884d 100644
--- a/web/src/pages/HomePage/HomePage.js
+++ b/web/src/pages/HomePage/HomePage.js
@@ -2,11 +2,13 @@ import MainLayout from 'src/layouts/MainLayout'
import PartsCell from 'src/components/PartsCell'
import LandingSection from 'src/components/LandingSection'
import Seo from 'src/components/Seo/Seo'
+import IdeToolbar from 'src/components/IdeToolbarNew'
const PartsPage = () => {
return (
+