Skip to content

Commit 23aed40

Browse files
committed
add sandbox ui update
1 parent 2937578 commit 23aed40

File tree

9 files changed

+217
-128
lines changed

9 files changed

+217
-128
lines changed

app/src/components/App.tsx

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,40 @@
1-
import React, {useEffect } from 'react';
21
import '../public/styles/style.css';
2+
3+
import React, { useEffect } from 'react';
4+
import {
5+
setInitialState,
6+
toggleLoggedIn
7+
} from '../redux/reducers/slice/appStateSlice';
8+
//redux toolkit addition
9+
import { useDispatch, useSelector } from 'react-redux';
10+
11+
import AppContainer from '../containers/AppContainer';
12+
import Cookies from 'js-cookie';
313
import { DndProvider } from 'react-dnd';
414
import { HTML5Backend } from 'react-dnd-html5-backend';
5-
import AppContainer from '../containers/AppContainer';
15+
import { RootState } from '../redux/store';
616
import localforage from 'localforage';
717
import { saveProject } from '../helperFunctions/projectGetSaveDel';
8-
import Cookies from 'js-cookie';
9-
//redux toolkit addition
10-
import { useSelector, useDispatch } from 'react-redux';
11-
import { setInitialState, toggleLoggedIn} from '../redux/reducers/slice/appStateSlice';
12-
13-
import { RootState } from '../redux/store';
1418

1519
// Intermediary component to wrap main App component with higher order provider components
1620
export const App = (): JSX.Element => {
1721
const state = useSelector((store: RootState) => store.appState);
1822
const dispatch = useDispatch();
1923
// checks if user is signed in as guest or actual user and changes loggedIn boolean accordingly
20-
useEffect(()=>{
24+
useEffect(() => {
2125
if (window.localStorage.getItem('ssid') !== 'guest') {
22-
dispatch(toggleLoggedIn())
23-
}
24-
},[])
26+
dispatch(toggleLoggedIn());
27+
}
28+
}, []);
2529

2630
// following useEffect runs on first mount
2731
useEffect(() => {
2832
// if user is a guest, see if a project exists in localforage and retrieve it
29-
if (!state.isLoggedIn) {
30-
localforage.getItem('guestProject').then(project => {
33+
if (!state.isLoggedIn) {
34+
localforage.getItem('guestProject').then((project) => {
3135
// if project exists, use dispatch to set initial state to that project
3236
if (project) {
33-
dispatch(setInitialState(project))
37+
dispatch(setInitialState(project));
3438
}
3539
});
3640
} else {
@@ -42,10 +46,9 @@ export const App = (): JSX.Element => {
4246
userId = window.localStorage.getItem('ssid');
4347
}
4448
//also load user's last project, which was saved in localforage on logout
45-
localforage.getItem(userId).then(project => {
49+
localforage.getItem(userId).then((project) => {
4650
if (project) {
47-
48-
dispatch(setInitialState(project))
51+
dispatch(setInitialState(project));
4952
} else {
5053
console.log(
5154
'No user project found in localforage, setting initial state blank'
@@ -96,12 +99,11 @@ export const App = (): JSX.Element => {
9699
>
97100
ReacType
98101
</header>
99-
100-
<AppContainer />
101-
102+
103+
<AppContainer />
102104
</DndProvider>
103105
</div>
104106
);
105-
}
107+
};
106108

107109
export default App;

app/src/components/left/DragDropPanel.tsx

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
import React from 'react';
1+
import { useDispatch, useSelector } from 'react-redux';
2+
23
import Grid from '@mui/material/Grid';
34
import HTMLItem from './HTMLItem';
5+
import React from 'react';
46
import { RootState } from '../../redux/store';
5-
import { useSelector, useDispatch } from 'react-redux';
67
import { deleteElement } from '../../redux/reducers/slice/appStateSlice';
78

89
/*
@@ -38,7 +39,7 @@ const DragDropPanel = (props): JSX.Element => {
3839
<div className={`${!isDarkMode ? 'HTMLItems' : 'HTMLItemsDark'}`}>
3940
<div id="HTMLItemsTopHalf">
4041
<Grid id="HTMLItemsGrid">
41-
<h3 style={{ color: !isDarkMode ? '#000' : '#fff' }}>
42+
<h3 style={{ color: !isDarkMode ? '#C6C6C6' : '#fff' }}>
4243
HTML ELEMENTS
4344
</h3>
4445
{htmlTypesToRender.map((option) => {
@@ -59,7 +60,7 @@ const DragDropPanel = (props): JSX.Element => {
5960
}
6061
})}
6162
{state.projectType === 'Classic React' ? (
62-
<h3 style={{ color: !isDarkMode ? '#000' : '#fff' }}>
63+
<h3 style={{ color: !isDarkMode ? '#C6C6C6' : '#fff' }}>
6364
REACT ROUTER
6465
</h3>
6566
) : null}
@@ -83,7 +84,7 @@ const DragDropPanel = (props): JSX.Element => {
8384
})}
8485

8586
{state.projectType === 'Next.js' ? (
86-
<h3 style={{ color: !isDarkMode ? '#000' : '#fff' }}>Next.js</h3>
87+
<h3 style={{ color: !isDarkMode ? '#C6C6C6' : '#fff' }}>Next.js</h3>
8788
) : null}
8889
{htmlTypesToRender.map((option) => {
8990
if (

app/src/components/left/HTMLItem.tsx

Lines changed: 54 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,19 @@
11
import React, { useState } from 'react';
2-
import { useDrag } from 'react-dnd';
3-
import { ItemTypes } from '../../constants/ItemTypes';
2+
43
import Grid from '@mui/material/Grid';
5-
import makeStyles from '@mui/styles/makeStyles';
4+
import { ItemTypes } from '../../constants/ItemTypes';
65
import List from '@mui/material/List';
76
import ListItem from '@mui/material/ListItem';
87
import ListItemText from '@mui/material/ListItemText';
8+
import { RootState } from '../../redux/store';
99
import createModal from '../right/createModal';
10+
import makeStyles from '@mui/styles/makeStyles';
11+
import { useDrag } from 'react-dnd';
1012
import { useSelector } from 'react-redux';
11-
import { RootState } from '../../redux/store';
1213

1314
const useStyles = makeStyles({
1415
HTMLPanelItem: {
15-
color: '#186BB4',
16+
color: '#8F8F8F',
1617
height: '35px',
1718
width: '90px',
1819
fontSize: '80%',
@@ -22,32 +23,32 @@ const useStyles = makeStyles({
2223
textAlign: 'center',
2324
margin: '7px auto',
2425
marginLeft: '30px',
25-
borderRadius: '25px',
2626
cursor: 'grab',
2727
'& > h3': {
28-
display: 'inline-block',
28+
display: 'inline-block'
2929
}
3030
},
3131
lightThemeFontColor: {
32-
color: '#292929'
32+
color: '#8F8F8F'
3333
},
3434
darkThemeFontColor: {
35-
color: '#fff'
35+
color: '#8F8F8F'
3636
}
37-
3837
});
3938

40-
const HTMLItem : React.FC<{
39+
const HTMLItem: React.FC<{
4140
name: string;
4241
id: number;
4342
Icon: any;
4443
handleDelete: (id: number) => void;
4544
}> = ({ name, id, handleDelete }) => {
46-
4745
const classes = useStyles();
4846
const [modal, setModal] = useState(null);
49-
const isDarkMode = useSelector((store:RootState) => store.darkMode.isDarkMode);
50-
const [{ isDragging }, drag] = useDrag({ // is dragging is never read, but if deleted adjustment in the ref are needed line 122/128 ref={drag} to {...drag}
47+
const isDarkMode = useSelector(
48+
(store: RootState) => store.darkMode.isDarkMode
49+
);
50+
const [{ isDragging }, drag] = useDrag({
51+
// is dragging is never read, but if deleted adjustment in the ref are needed line 122/128 ref={drag} to {...drag}
5152
item: {
5253
type: ItemTypes.INSTANCE,
5354
newInstance: true,
@@ -72,7 +73,7 @@ const HTMLItem : React.FC<{
7273
key={`clear${deleteID}`}
7374
onClick={() => handleDelete(deleteID)}
7475
style={{
75-
border: '1px solid #3f51b5',
76+
border: '1px solid #C6C6C6',
7677
marginBottom: '2%',
7778
marginTop: '5%'
7879
}}
@@ -87,7 +88,7 @@ const HTMLItem : React.FC<{
8788
key={`close${deleteID}`}
8889
onClick={closeModal}
8990
style={{
90-
border: '1px solid #3f51b5',
91+
border: '1px solid #C6C6C6',
9192
marginBottom: '2%',
9293
marginTop: '5%'
9394
}}
@@ -106,7 +107,8 @@ const HTMLItem : React.FC<{
106107
createModal({
107108
closeModal,
108109
children,
109-
message: 'Deleting this element will delete all instances of this element within the application.\nDo you still wish to proceed?',
110+
message:
111+
'Deleting this element will delete all instances of this element within the application.\nDo you still wish to proceed?',
110112
primBtnLabel: null,
111113
primBtnAction: null,
112114
secBtnAction: null,
@@ -116,24 +118,49 @@ const HTMLItem : React.FC<{
116118
);
117119
};
118120
// updated the id's to reflect the new element types input and label
119-
return ( // HTML Elements
121+
return (
122+
// HTML Elements
120123
<Grid item xs={5} key={`html-g${name}`}>
121-
{ id <= 20 &&
122-
<div ref={drag} style={ { borderColor: !isDarkMode ? '#000' : '#fff' } } className={!isDarkMode ? `${classes.HTMLPanelItem} ${classes.lightThemeFontColor}` : `${classes.HTMLPanelItem} ${classes.darkThemeFontColor}`} id="HTMLItem">
124+
{id <= 20 && (
125+
<div
126+
ref={drag}
127+
style={{ borderColor: !isDarkMode ? '#C6C6C6' : '#fff' }}
128+
className={
129+
!isDarkMode
130+
? `${classes.HTMLPanelItem} ${classes.lightThemeFontColor}`
131+
: `${classes.HTMLPanelItem} ${classes.darkThemeFontColor}`
132+
}
133+
id="HTMLItem"
134+
>
123135
<h3>{name}</h3>
124136
</div>
125-
}
126-
{ id > 20 &&
137+
)}
138+
{id > 20 && (
127139
<span id="customHTMLElement">
128-
<div ref={drag} style={ { borderColor: !isDarkMode ? '#000' : '#fff' } } className={!isDarkMode ? `${classes.HTMLPanelItem} ${classes.lightThemeFontColor}` : `${classes.HTMLPanelItem} ${classes.darkThemeFontColor}`} id="HTMLItem">
140+
<div
141+
ref={drag}
142+
style={{ borderColor: !isDarkMode ? '#C6C6C6' : '#fff' }}
143+
className={
144+
!isDarkMode
145+
? `${classes.HTMLPanelItem} ${classes.lightThemeFontColor}`
146+
: `${classes.HTMLPanelItem} ${classes.darkThemeFontColor}`
147+
}
148+
id="HTMLItem"
149+
>
129150
<h3>{name}</h3>
130151
</div>
131-
<button id="newElement" style={{color: !isDarkMode ? '#186BB4' : 'white' }} onClick={() => deleteAllInstances(id)} >X</button>
152+
<button
153+
id="newElement"
154+
style={{ color: !isDarkMode ? '#C6C6C6' : 'white' }}
155+
onClick={() => deleteAllInstances(id)}
156+
>
157+
X
158+
</button>
132159
</span>
133-
}
160+
)}
134161
{modal}
135162
</Grid>
136163
);
137-
}
164+
};
138165

139-
export default HTMLItem;
166+
export default HTMLItem;

app/src/components/main/DemoRender.tsx

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1+
import { Link, Route, BrowserRouter as Router, Switch } from 'react-router-dom';
12
import React, { useEffect, useRef } from 'react';
2-
import { BrowserRouter as Router, Switch, Route, Link } from 'react-router-dom';
3+
import { useDispatch, useSelector } from 'react-redux';
4+
35
import Box from '@mui/material/Box';
46
import { Component } from '../../interfaces/Interfaces';
57
import ReactDOMServer from 'react-dom/server';
6-
import { useDispatch, useSelector } from 'react-redux';
7-
import { changeFocus } from '../../redux/reducers/slice/appStateSlice';
88
import { RootState } from '../../redux/store';
9+
import { changeFocus } from '../../redux/reducers/slice/appStateSlice';
910

1011
// DemoRender is the full sandbox demo of our user's custom built React components. DemoRender references the design specifications stored in state to construct
1112
// real react components that utilize hot module reloading to depict the user's prototype application.
@@ -54,14 +55,22 @@ const DemoRender = (): JSX.Element => {
5455

5556
//Switch between components when clicking on a link in the live render
5657
window.onmessage = (event) => {
57-
if (event.data === undefined) return;
58-
const component: string = event.data.data?.split('/').at(-1);
59-
const componentId =
60-
component &&
61-
state.components?.find((el) => {
62-
return el.name.toLowerCase() === component.toLowerCase();
63-
}).id;
64-
componentId && dispatch(changeFocus({ componentId, childId: null }));
58+
// If event.data or event.data.data is undefined, return early
59+
if (!event.data || typeof event.data.data !== 'string') return;
60+
61+
const component: string = event.data.data.split('/').at(-1);
62+
63+
// If components aren't defined or component isn't a string, return early
64+
if (!state.components || !component) return;
65+
66+
const matchedComponent = state.components.find(
67+
(el) => el.name.toLowerCase() === component.toLowerCase()
68+
);
69+
70+
// If matchedComponent is undefined or doesn't have an id, return early
71+
if (!matchedComponent || matchedComponent.id === undefined) return;
72+
73+
dispatch(changeFocus({ componentId: matchedComponent.id, childId: null }));
6574
};
6675

6776
// This function is the heart of DemoRender it will take the array of components stored in state and dynamically construct the desired React component for the live demo

app/src/components/top/NavBar.tsx

Lines changed: 37 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,49 @@
1-
import React from 'react';
21
import Avatar from '@mui/material/Avatar';
2+
import NavbarDropDown from './NavBarButtons';
3+
import React from 'react';
4+
import { RootState } from '../../redux/store';
35
//commenting out the line below breaks the app
46
import logo from '../../public/icons/win/logo.png';
5-
import NavbarDropDown from './NavBarButtons';
67
import { useSelector } from 'react-redux';
7-
import { RootState } from '../../redux/store';
8-
98

109
const NavBar = (props) => {
11-
1210
// for dropdown navbar
1311
const [dropMenu, setDropMenu] = React.useState(false);
14-
const isDarkMode = useSelector((state:RootState)=>state.darkMode.isDarkMode)
12+
const isDarkMode = useSelector(
13+
(state: RootState) => state.darkMode.isDarkMode
14+
);
1515

1616
return (
17-
<nav className="main-navbar" style={isDarkMode ? {backgroundColor: '#013365'} : {backgroundColor: 'white'}}>
18-
<div className="main-logo">
19-
<Avatar src={logo}></Avatar>
20-
<h1 style={isDarkMode ? {color: 'white'} : {color: '#013365'}}>ReacType</h1>
21-
</div>
22-
<div onMouseLeave={()=>setDropMenu(false)}>
23-
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" className="bi bi-gear-wide-connected navbar-icon" viewBox="0 0 16 16"
24-
onMouseOver={()=>setDropMenu(true)}>
25-
<path d="M7.068.727c.243-.97 1.62-.97 1.864 0l.071.286a.96.96 0 0 0 1.622.434l.205-.211c.695-.719 1.888-.03 1.613.931l-.08.284a.96.96 0 0 0 1.187 1.187l.283-.081c.96-.275 1.65.918.931 1.613l-.211.205a.96.96 0 0 0 .434 1.622l.286.071c.97.243.97 1.62 0 1.864l-.286.071a.96.96 0 0 0-.434 1.622l.211.205c.719.695.03 1.888-.931 1.613l-.284-.08a.96.96 0 0 0-1.187 1.187l.081.283c.275.96-.918 1.65-1.613.931l-.205-.211a.96.96 0 0 0-1.622.434l-.071.286c-.243.97-1.62.97-1.864 0l-.071-.286a.96.96 0 0 0-1.622-.434l-.205.211c-.695.719-1.888.03-1.613-.931l.08-.284a.96.96 0 0 0-1.186-1.187l-.284.081c-.96.275-1.65-.918-.931-1.613l.211-.205a.96.96 0 0 0-.434-1.622l-.286-.071c-.97-.243-.97-1.62 0-1.864l.286-.071a.96.96 0 0 0 .434-1.622l-.211-.205c-.719-.695-.03-1.888.931-1.613l.284.08a.96.96 0 0 0 1.187-1.186l-.081-.284c-.275-.96.918-1.65 1.613-.931l.205.211a.96.96 0 0 0 1.622-.434l.071-.286zM12.973 8.5H8.25l-2.834 3.779A4.998 4.998 0 0 0 12.973 8.5zm0-1a4.998 4.998 0 0 0-7.557-3.779l2.834 3.78h4.723zM5.048 3.967c-.03.021-.058.043-.087.065l.087-.065zm-.431.355A4.984 4.984 0 0 0 3.002 8c0 1.455.622 2.765 1.615 3.678L7.375 8 4.617 4.322zm.344 7.646.087.065-.087-.065z"/>
26-
</svg>
27-
<NavbarDropDown dropMenu={dropMenu}></NavbarDropDown>
28-
</div>
29-
</nav>
30-
)
31-
}
17+
<nav
18+
className="main-navbar"
19+
style={
20+
isDarkMode
21+
? { backgroundColor: '#013365' }
22+
: { backgroundColor: '#151515' }
23+
}
24+
>
25+
<div className="main-logo">
26+
<Avatar src={logo}></Avatar>
27+
<h1 style={isDarkMode ? { color: '#C6C6C6' } : { color: '#C6C6C6' }}>
28+
ReacType
29+
</h1>
30+
</div>
31+
<div onMouseLeave={() => setDropMenu(false)}>
32+
<svg
33+
xmlns="http://www.w3.org/2000/svg"
34+
width="16"
35+
height="16"
36+
fill="currentColor"
37+
className="bi bi-gear-wide-connected navbar-icon"
38+
viewBox="0 0 16 16"
39+
onMouseOver={() => setDropMenu(true)}
40+
>
41+
<path d="M7.068.727c.243-.97 1.62-.97 1.864 0l.071.286a.96.96 0 0 0 1.622.434l.205-.211c.695-.719 1.888-.03 1.613.931l-.08.284a.96.96 0 0 0 1.187 1.187l.283-.081c.96-.275 1.65.918.931 1.613l-.211.205a.96.96 0 0 0 .434 1.622l.286.071c.97.243.97 1.62 0 1.864l-.286.071a.96.96 0 0 0-.434 1.622l.211.205c.719.695.03 1.888-.931 1.613l-.284-.08a.96.96 0 0 0-1.187 1.187l.081.283c.275.96-.918 1.65-1.613.931l-.205-.211a.96.96 0 0 0-1.622.434l-.071.286c-.243.97-1.62.97-1.864 0l-.071-.286a.96.96 0 0 0-1.622-.434l-.205.211c-.695.719-1.888.03-1.613-.931l.08-.284a.96.96 0 0 0-1.186-1.187l-.284.081c-.96.275-1.65-.918-.931-1.613l.211-.205a.96.96 0 0 0-.434-1.622l-.286-.071c-.97-.243-.97-1.62 0-1.864l.286-.071a.96.96 0 0 0 .434-1.622l-.211-.205c-.719-.695-.03-1.888.931-1.613l.284.08a.96.96 0 0 0 1.187-1.186l-.081-.284c-.275-.96.918-1.65 1.613-.931l.205.211a.96.96 0 0 0 1.622-.434l.071-.286zM12.973 8.5H8.25l-2.834 3.779A4.998 4.998 0 0 0 12.973 8.5zm0-1a4.998 4.998 0 0 0-7.557-3.779l2.834 3.78h4.723zM5.048 3.967c-.03.021-.058.043-.087.065l.087-.065zm-.431.355A4.984 4.984 0 0 0 3.002 8c0 1.455.622 2.765 1.615 3.678L7.375 8 4.617 4.322zm.344 7.646.087.065-.087-.065z" />
42+
</svg>
43+
<NavbarDropDown dropMenu={dropMenu}></NavbarDropDown>
44+
</div>
45+
</nav>
46+
);
47+
};
3248

3349
export default NavBar;

0 commit comments

Comments
 (0)