Skip to content

Commit e731891

Browse files
committed
added additional regex to components and custom elements
1 parent 11b6f30 commit e731891

File tree

7 files changed

+199
-41
lines changed

7 files changed

+199
-41
lines changed

app/src/components/bottom/CodePreview.tsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useContext } from 'react';
1+
import React, { useContext, useState } from 'react';
22
import { stateContext } from '../../context/context';
33
import AceEditor from 'react-ace';
44
import { makeStyles } from '@material-ui/core/styles';
@@ -13,6 +13,10 @@ const CodePreview = () => {
1313
(elem: Component) => elem.id === state.canvasFocus.componentId
1414
);
1515

16+
const handleCodeSnipChange = val => {
17+
currentComponent.code = val;
18+
}
19+
1620
return (
1721
<div
1822
style={{
@@ -41,10 +45,11 @@ const CodePreview = () => {
4145
// code
4246
// })
4347
// }
48+
onChange={handleCodeSnipChange}
4449
value={currentComponent.code}
4550
name="Code_div"
4651
// readOnly={this.props.codeReadOnly}
47-
readOnly={true}
52+
readOnly={false}
4853
editorProps={{ $blockScrolling: true }}
4954
fontSize={16}
5055
tabSize={2}

app/src/components/left/ComponentPanel.tsx

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ const ComponentPanel = (): JSX.Element => {
3232
setErrorMsg('Component name already exists.');
3333
} else if (type === 'letters') {
3434
setErrorMsg('Component name must start with a letter.');
35+
} else if (type === 'symbolsDetected') {
36+
setErrorMsg('Component name must not contain symbols.');
3537
}
3638
};
3739

@@ -81,11 +83,20 @@ const ComponentPanel = (): JSX.Element => {
8183
setCompName('');
8284
};
8385

86+
const alphanumeric = input => {
87+
let letterNumber = /^[0-9a-zA-Z]+$/;
88+
if (input.match(letterNumber)) return true;
89+
return false;
90+
}
91+
8492
const handleNameSubmit = () => {
8593
let letters = /[a-zA-Z]/;
8694
if (!compName.charAt(0).match(letters)) {
8795
triggerError('letters');
8896
return;
97+
} else if (!alphanumeric(compName)) {
98+
triggerError('symbolsDetected');
99+
return;
89100
} else if (compName.trim() === '') {
90101
triggerError('empty');
91102
return;
@@ -101,11 +112,11 @@ const ComponentPanel = (): JSX.Element => {
101112
return state.canvasFocus.componentId === targetId ? true : false;
102113
};
103114

104-
const deleteReusableComponent = (id) => {
105-
// reducer to modify state.components
106-
// make sure the component is not a root
107-
//
108-
}
115+
// const deleteReusableComponent = (id) => {
116+
// // reducer to modify state.components
117+
// // make sure the component is not a root
118+
// //
119+
// }
109120

110121
return (
111122
<div className={classes.panelWrapper}>

app/src/components/left/HTMLPanel.tsx

Lines changed: 166 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,68 @@ import React, { useState, useContext } from 'react';
22
import Grid from '@material-ui/core/Grid';
33
import { stateContext } from '../../context/context';
44
import HTMLItem from './HTMLItem';
5+
import { makeStyles } from '@material-ui/core/styles';
56

67
const HTMLPanel = (): JSX.Element => {
8+
const classes = useStyles();
9+
710
const [tag, setTag] = useState('');
811
const [name, setName] = useState('');
912
const [currentID, setCurrentID] = useState(12);
1013
const [state, dispatch] = useContext(stateContext);
14+
const [errorMsg, setErrorMsg] = useState('');
15+
const [errorStatus, setErrorStatus] = useState(false);
16+
1117

1218
const handleTagChange = (e: React.ChangeEvent<HTMLInputElement>) => {
19+
resetError();
1320
setTag(e.target.value);
14-
}
21+
};
1522

1623
const handleNameChange = (e: React.ChangeEvent<HTMLInputElement>) => {
24+
resetError();
1725
setName(e.target.value);
18-
}
26+
};
1927

20-
const handleSubmit = (e) => {
21-
e.preventDefault();
28+
const checkNameDupe = (inputName: String) => {
29+
let checkList = state.HTMLTypes.slice();
30+
31+
// checks to see if inputted comp name already exists
32+
let dupe = false;
33+
checkList.forEach(HTMLTag => {
34+
if ((HTMLTag.name.toLowerCase() === inputName.toLowerCase()) || (HTMLTag.tag.toLowerCase() === inputName.toLowerCase())) {
35+
dupe = true;
36+
}
37+
});
38+
return dupe;
39+
};
40+
41+
const triggerError = (type: String) => {
42+
setErrorStatus(true);
43+
if (type === 'empty') {
44+
setErrorMsg('Tag/ Tag name cannot be blank.');
45+
} else if (type === 'dupe') {
46+
setErrorMsg('Tag/ Tag name already exists.');
47+
} else if (type === 'letters') {
48+
setErrorMsg('Tag/ Tag name must start with a letter.');
49+
} else if (type === 'symbolsDetected') {
50+
setErrorMsg('Tag/ Tag name must not contain symbols.');
51+
}
52+
};
53+
54+
const resetError = () => {
55+
setErrorStatus(false);
56+
};
57+
58+
const createOption = (inputTag: String, inputName: String) => {
59+
// format name so first letter is capitalized and there are no whitespaces
60+
let inputNameClean = inputName.replace(/\s+/g, '');
61+
const formattedName = inputNameClean.charAt(0).toUpperCase() + inputNameClean.slice(1);
62+
// add new component to state
2263
const newElement = {
2364
id: currentID,
24-
tag,
25-
name,
65+
tag: inputTag,
66+
name: formattedName,
2667
style: {},
2768
placeHolderShort: name,
2869
placeHolderLong: '',
@@ -35,25 +76,56 @@ const HTMLPanel = (): JSX.Element => {
3576
setCurrentID(currentID + 1);
3677
setTag('');
3778
setName('');
38-
console.log("SUBMIT BUTTON CLICKED: ", newElement);
79+
};
80+
81+
const alphanumeric = input => {
82+
let letterNumber = /^[0-9a-zA-Z]+$/;
83+
if (input.match(letterNumber)) return true;
84+
return false;
85+
}
86+
87+
const handleSubmit = (e) => {
88+
e.preventDefault();
89+
let letters = /[a-zA-Z]/;
90+
if ((!tag.charAt(0).match(letters)) || (!name.charAt(0).match(letters))) {
91+
triggerError('letters');
92+
return;
93+
} else if (!alphanumeric(tag) || !alphanumeric(name)) {
94+
triggerError('symbolsDetected');
95+
return;
96+
} else if ((tag.trim() === '') || (name.trim() === '')) {
97+
triggerError('empty');
98+
return;
99+
} else if (checkNameDupe(tag) || checkNameDupe(name)) {
100+
triggerError('dupe');
101+
return;
102+
}
103+
createOption(tag, name);
104+
resetError();
39105
}
40106

41107
return (
42108
<div>
43109
<h4> HTML Elements</h4>
44-
<div>
45-
<form onSubmit={handleSubmit}>
46-
<h4>Create New Element: </h4>
47-
<label>
48-
Tag:
49-
<input type="text" name="Tag" value={tag} onChange={handleTagChange} />
50-
</label>
51-
<label>
52-
Tag Name:
53-
<input type="text" name="Tag Name" value={name} onChange={handleNameChange} />
54-
</label>
55-
<input type="submit" value="Add Element" />
56-
</form>
110+
<div className={classes.addComponentWrapper}>
111+
<div className={classes.inputWrapper} >
112+
<form onSubmit={handleSubmit} >
113+
<h4>Create New Element: </h4>
114+
<label className={classes.inputLabel}>
115+
Tag:
116+
<input color={'primary'} type="text" name="Tag" value={tag} onChange={handleTagChange} className={classes.input} />
117+
{errorStatus &&
118+
<span>{errorMsg}</span>}
119+
</label>
120+
<label className={classes.inputLabel}>
121+
Tag Name:
122+
<input color={'primary'} type="text" name="Tag Name" value={name} onChange={handleNameChange} className={classes.input} />
123+
{errorStatus &&
124+
<span>{errorMsg}</span>}
125+
</label>
126+
<input className={classes.button} color="primary" type="submit" value="Add Element" />
127+
</form>
128+
</div>
57129
</div>
58130
<Grid
59131
container
@@ -75,4 +147,78 @@ const HTMLPanel = (): JSX.Element => {
75147
);
76148
};
77149

150+
const useStyles = makeStyles({
151+
inputField: {
152+
marginTop: '15px'
153+
},
154+
inputWrapper: {
155+
// height: '115px',
156+
textAlign: 'center',
157+
display: 'flex',
158+
alignItems: 'center',
159+
justifyContent: 'space-between',
160+
// paddingLeft: '35px',
161+
marginBottom: '15px'
162+
},
163+
addComponentWrapper: {
164+
border: '1px solid rgba(70,131,83)',
165+
padding: '20px',
166+
margin: '20px'
167+
},
168+
rootCheckBox: {},
169+
rootCheckBoxLabel: {
170+
color: 'white'
171+
},
172+
panelWrapper: {
173+
width: '100%',
174+
marginTop: '15px'
175+
},
176+
panelWrapperList: {
177+
// maxHeight: '400px',
178+
minHeight: '120px',
179+
// overflowY: 'auto',
180+
marginLeft: '-15px',
181+
marginRight: '-15px'
182+
},
183+
panelSubheader: {
184+
textAlign: 'center',
185+
color: '#fff'
186+
},
187+
input: {
188+
color: '#fff',
189+
borderRadius: '5px',
190+
paddingLeft: '15px',
191+
paddingRight: '10px',
192+
whiteSpace: 'nowrap',
193+
overflowX: 'hidden',
194+
textOverflow: 'ellipsis',
195+
border: '1px solid rgba(51,235,145,0.75)',
196+
backgroundColor: 'rgba(255,255,255,0.15)'
197+
},
198+
inputLabel: {
199+
fontSize: '14px',
200+
zIndex: 20,
201+
color: '#fff',
202+
marginTop: '-10px'
203+
},
204+
btnGroup: {
205+
display: 'flex',
206+
flexDirection: 'column',
207+
paddingTop: '10px',
208+
marginLeft: '10px'
209+
},
210+
button: {
211+
fontSize: '1rem',
212+
height: '40px',
213+
maginTop: '10px',
214+
width: '100%',
215+
// border: '1px solid rgba(70,131,83)',
216+
backgroundColor: 'rgba(1,212,109,0.1)'
217+
},
218+
rootToggle: {
219+
color: '#01d46d',
220+
fontSize: '0.85rem'
221+
}
222+
});
223+
78224
export default HTMLPanel;

app/src/components/main/DirectChildComponent.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import { ItemTypes } from '../../constants/ItemTypes';
1010
import { stateContext } from '../../context/context';
1111
import { combineStyles } from '../../helperFunctions/combineStyles';
1212
import IndirectChild from './IndirectChild';
13-
import HTMLTypes from '../../context/HTMLTypes';
1413
import globalDefaultStyle from '../../public/styles/globalDefaultStyles';
1514

1615
function DirectChildComponent({ childId, type, typeId, style }: ChildElement) {
@@ -104,7 +103,7 @@ function DirectChildComponent({ childId, type, typeId, style }: ChildElement) {
104103
// if the HTML element has children, then also render its children
105104
// get the default style/placeholder value for that type of HTML element
106105
// combine the default style of that HTML element and combine in with the custom styles applied to that element
107-
const HTMLType: HTMLType = HTMLTypes.find(
106+
const HTMLType: HTMLType = state.HTMLTypes.find(
108107
(type: HTMLType) => type.id === child.typeId
109108
);
110109
const HTMLDefaultStyle = HTMLType.style;

app/src/components/main/DirectChildHTMLNestable.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import { useDrag, useDrop, DropTargetMonitor } from 'react-dnd';
44
import { ItemTypes } from '../../constants/ItemTypes';
55
import { stateContext } from '../../context/context';
66
import { combineStyles } from '../../helperFunctions/combineStyles';
7-
import HTMLTypes from '../../context/HTMLTypes';
87
import globalDefaultStyle from '../../public/styles/globalDefaultStyles';
98
import renderChildren from '../../helperFunctions/renderChildren';
109

@@ -20,7 +19,7 @@ function DirectChildHTMLNestable({
2019

2120
// find the HTML element corresponding with this instance of an HTML element
2221
// find the current component to render on the canvas
23-
const HTMLType: HTMLType = HTMLTypes.find(
22+
const HTMLType: HTMLType = state.HTMLTypes.find(
2423
(type: HTMLType) => type.id === typeId
2524
);
2625

app/src/components/right/DeleteProjects.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ const useStyles = makeStyles({
118118
fontSize: '1em',
119119
minWidth: '300px',
120120
marginTop: '10px',
121-
marginBotton: '10px'
121+
marginBottom: '10px'
122122
},
123123
avatar: {
124124
backgroundColor: blue[100],

0 commit comments

Comments
 (0)