Skip to content

Commit 35eb5b6

Browse files
committed
Css edits
2 parents 2a07a08 + 1b478f7 commit 35eb5b6

24 files changed

+372
-131
lines changed

app/src/components/App.tsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import '../public/styles/style.css';
22

3-
import React, { useEffect } from 'react';
3+
import React, { useEffect, useState } from 'react';
44
import {
55
setInitialState,
66
toggleLoggedIn
@@ -19,16 +19,20 @@ import { saveProject } from '../helperFunctions/projectGetSaveDel';
1919
// Intermediary component to wrap main App component with higher order provider components
2020
export const App = (): JSX.Element => {
2121
const state = useSelector((store: RootState) => store.appState);
22+
const [toggleAttempt, setToggleAttempt] = useState(false);
2223
const dispatch = useDispatch();
2324
// checks if user is signed in as guest or actual user and changes loggedIn boolean accordingly
2425
useEffect(() => {
2526
if (window.localStorage.getItem('ssid') !== 'guest') {
26-
dispatch(toggleLoggedIn());
27+
dispatch(toggleLoggedIn(true));
2728
}
29+
//setToggleAttempt(!toggleAttempt);
2830
}, []);
2931

3032
// following useEffect runs on first mount
3133
useEffect(() => {
34+
console.log('state.isLoggedIn', state.isLoggedIn)
35+
// console.log('cookies.get in App', Cookies.get())
3236
// if user is a guest, see if a project exists in localforage and retrieve it
3337
if (!state.isLoggedIn) {
3438
localforage.getItem('guestProject').then((project) => {
@@ -39,6 +43,7 @@ export const App = (): JSX.Element => {
3943
});
4044
} else {
4145
// otherwise if a user is logged in, use a fetch request to load user's projects from DB
46+
4247
let userId;
4348
if (Cookies.get('ssid')) {
4449
userId = Cookies.get('ssid');

app/src/components/main/CanvasContainer.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ function CanvasContainer(props): JSX.Element {
1919
// onClickCodePreview swaps the rendered component from the canvas to the code preview editor
2020
const onClickCodePreview = () => {
2121
dispatch(toggleCodePreview());
22-
console.log(state.codePreview);
2322
}
2423

2524
const canvasContainerStyle = {

app/src/components/main/DemoRender.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ const DemoRender = (): JSX.Element => {
8282
const elementType = element.name;
8383
const childId = element.childId;
8484
const elementStyle = element.style;
85-
const innerText = element.attributes.compText;
85+
const innerText = element.attributes.compText;
8686
const classRender = element.attributes.cssClasses;
8787
const activeLink = element.attributes.compLink;
8888
let renderedChildren;

app/src/components/marketplace/MarketplaceCard.tsx

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,11 @@ import React from 'react';
1818
import imageSrc from '../../../../resources/marketplace_images/marketplace_image.png';
1919
import { red } from '@mui/material/colors';
2020
import axios from 'axios';
21-
import {useDispatch, useSelector} from 'react-redux'
21+
import { useDispatch, useSelector } from 'react-redux'
2222
import { RootState } from '../../redux/store';
2323
import { saveProject } from '../../helperFunctions/projectGetSaveDel';
24+
import { useHistory } from 'react-router-dom';
25+
import { openProject } from '../../redux/reducers/slice/appStateSlice';
2426

2527
interface Project {
2628
forked: String,
@@ -37,21 +39,27 @@ interface Project {
3739

3840
const ITEM_HEIGHT = 48;
3941
const MarketplaceCard = ({proj} :{proj: Project}) => {
42+
const dispatch = useDispatch();
43+
const history = useHistory();
4044
const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null);
4145
const open = Boolean(anchorEl);
4246
const state = useSelector((store:RootState) => store.appState);
43-
console.log('HEY', state)
4447
const handleClick = (event: React.MouseEvent<HTMLElement>) => {
4548
setAnchorEl(event.currentTarget);
4649
};
4750
const handleClone = async () => { // creates a copy of the project
48-
const updatedProject: Project = JSON.parse(JSON.stringify(proj)); // creates a deep copy
49-
updatedProject.forked = `Forked from ${updatedProject.username}`;
50-
await axios.post('/cloneProject', {
51-
updatedProject
52-
});
51+
const docId = proj._id;
52+
const response = await axios.get(`/cloneProject/${docId}`, { params: { username: window.localStorage.getItem('username') } });//passing in username as a query param is query params
53+
const project = response.data.project;
5354
alert('Project cloned!');
5455
setAnchorEl(null);
56+
return project;
57+
};
58+
59+
const handleCloneOpen = async() => {
60+
const project = await handleClone();
61+
history.push('/');
62+
dispatch(openProject(project));
5563
};
5664
const handleClose = () => {
5765
setAnchorEl(null);
@@ -110,11 +118,19 @@ const MarketplaceCard = ({proj} :{proj: Project}) => {
110118
<MenuItem
111119
onClick={handleClone}
112120
sx={{
113-
color: '#C6C6C6'
121+
color: '#fff'
114122
}}
115123
>
116124
Clone
117125
</MenuItem>
126+
<MenuItem
127+
onClick={handleCloneOpen}
128+
sx={{
129+
color: '#fff'
130+
}}
131+
>
132+
Clone and open
133+
</MenuItem>
118134
</Menu>
119135
</Card>
120136
</>

app/src/components/marketplace/Searchbar.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,12 @@ const SearchBar = ({marketplaceProjects, updateDisplayProjects }):JSX.Element =>
2929
//a-zA-Z letters (lowercase and uppercase) and underscore symbol
3030
//All together: match either the start/end of a line/string or any character that is not a letter.
3131
//Looks for anything that has the searchText in between non-letter characters
32+
const patternString2 = '(?:^|.)' + searchText.toLowerCase() + '(?:$|.)';
33+
//Only difference is that (?:^|.) (?:$|.) look for anything that matches the string in between any other characters for the username search
34+
//test3 and 1test) would both match for string 'test'
35+
3236
const searchResults = marketplaceProjects.reduce((results, curr) => {
33-
if(curr.name.match(patternString) || curr.username.match(patternString))
37+
if(curr.name.match(patternString) || curr.username.match(patternString2))
3438
results.push(curr)
3539
return results;
3640
}, [])

app/src/components/right/LoginButton.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,19 @@ import { useSelector, useDispatch } from 'react-redux';
33
import { toggleLoggedIn } from '../../redux/reducers/slice/appStateSlice';
44
import config from '../../../../config.js';
55
import { RootState } from '../../redux/store';
6+
import Cookies from 'js-cookie';
67
// note that API_BASE_URL is assigned to different pages on dev mode vs prod mode
78
const { API_BASE_URL, API_BASE_URL2 } = config;
89

910
export default function LoginButton() {
1011
const state = useSelector((store:RootState) => store.appState);
1112
const dispatch = useDispatch();
12-
1313
const handleLogout = () => {
14+
1415
window.localStorage.clear();
15-
document.cookie = 'ssid' + '=; Max-Age=0';
1616

1717
if (state.isLoggedIn) {
18-
dispatch(toggleLoggedIn());
18+
dispatch(toggleLoggedIn(false));
1919
}
2020

2121
window.location.href = state.isLoggedIn

app/src/components/right/OpenProjects.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ export interface ProjectDialogProps {
2424
function ProjectsDialog(props: ProjectDialogProps) {
2525
const classes = useStyles();
2626
const { onClose, open, projects } = props;
27-
console.log(projects)
2827
const state = useSelector((store:RootState) => store.appState);
2928
const dispatch = useDispatch();
3029
// If no projects selected, keep the name of the current displayed

app/src/components/right/SaveProjectButton.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@ import DialogTitle from '@mui/material/DialogTitle';
88
import SaveOutlinedIcon from '@mui/icons-material/SaveOutlined';
99
import { saveProject } from '../../helperFunctions/projectGetSaveDel';
1010
import {useDispatch, useSelector} from 'react-redux'
11-
import {updateProjectName} from '../../redux/reducers/slice/appStateSlice';
11+
import {updateProjectName, updateProjectId} from '../../redux/reducers/slice/appStateSlice';
1212
import { RootState } from '../../redux/store';
13+
import { State } from '../../interfaces/Interfaces';
1314

1415
export default function FormDialog() {
1516
const [open, setOpen] = useState(false);
@@ -34,7 +35,7 @@ const dispatch = useDispatch();
3435
// If errors occur on the backend, the project name still gets updated
3536

3637
dispatch(updateProjectName(projectName))
37-
saveProject(projectName, state);
38+
saveProject(projectName, state).then((project: State) => dispatch(updateProjectId(project._id)))//updates the slice with new _id from mongo
3839
setOpen(false);
3940
} else {
4041
setInvalidProjectName(true);

app/src/components/top/NavBar.tsx

Lines changed: 66 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,36 @@
1-
import React, { useState } from 'react';
1+
import React, { useEffect, useState } from 'react';
22
import { Link } from 'react-router-dom';
33
import Avatar from '@mui/material/Avatar';
44
import Button from '@mui/material/Button';
55
import MoreVertIcon from '@mui/icons-material/MoreVert';
66
import NavBarButtons from './NavBarButtons';
7-
import NavbarDropDown from './NavBarButtons';
87
import NewExportButton from './NewExportButton';
98
import { RootState } from '../../redux/store';
109
import logo from '../../public/icons/win/logo.png';
11-
import { useSelector } from 'react-redux';
10+
import { useSelector, useDispatch } from 'react-redux';
11+
import { publishProject } from '../../helperFunctions/projectGetSaveDel';
12+
import PublishModal from './PublishModal';
13+
import { updateProjectId, updateProjectName, updateProjectPublished } from '../../redux/reducers/slice/appStateSlice';
14+
import { State } from '../../interfaces/Interfaces';
15+
1216

1317
const NavBar = () => {
1418
const [dropMenu, setDropMenu] = useState(false);
19+
const state = useSelector((store: RootState) => store.appState);
20+
const [publishModalOpen, setPublishModalOpen] = useState(false);
21+
const [projectName, setProjectName] = useState(state.name || '');
22+
const [invalidProjectName, setInvalidProjectName] = useState(false);
23+
const [invalidProjectNameMessage, setInvalidProjectNameMessage] = useState('');
1524
const isDarkMode = useSelector(
1625
(state: RootState) => state.darkMode.isDarkMode
1726
);
1827

28+
const dispatch = useDispatch();
29+
30+
useEffect(()=>{
31+
setProjectName(state.name)
32+
}, [state.name])//update the ProjectName after state.name changes due to loading projects
33+
1934
const buttonContainerStyle = {
2035
display: 'flex',
2136
alignItems: 'center',
@@ -49,6 +64,35 @@ const NavBar = () => {
4964
marginRight: '10px'
5065
};
5166

67+
const handlePublish = () => {
68+
console.log('projectName', projectName)
69+
console.log('state.name', state.name)
70+
if (state.isLoggedIn === true && projectName === '') {
71+
setInvalidProjectName(true);
72+
setPublishModalOpen(true);
73+
return;
74+
}
75+
76+
77+
publishProject(state, projectName)
78+
.then((newProject: State) => {
79+
console.log('Project published successfully', newProject);
80+
setPublishModalOpen(false);
81+
dispatch(updateProjectId(newProject._id))
82+
dispatch(updateProjectName(newProject.name))
83+
dispatch(updateProjectPublished(newProject.published))
84+
})
85+
.catch((error) => {
86+
console.error('Error publishing project:', error.message);
87+
});
88+
89+
};
90+
91+
useEffect(()=>{
92+
console.log('stateName = ',state.name);
93+
console.log('published =', state.published);
94+
}, [state.name, state.published])
95+
5296
return (
5397
<nav
5498
className="main-navbar"
@@ -59,15 +103,17 @@ const NavBar = () => {
59103
}
60104
>
61105
<Link to="/" style={{ textDecoration: 'none' }}>
62-
<div className="main-logo">
63-
<Avatar src={logo}></Avatar>
64-
<h1 style={isDarkMode ? { color: 'white' } : { color: 'white' }}>
65-
ReacType
66-
</h1>
67-
</div>
68-
</Link>
106+
<div className="main-logo">
107+
<Avatar src={logo}></Avatar>
108+
<h1 style={isDarkMode ? { color: 'white' } : { color: 'white' }}>
109+
ReacType
110+
</h1>
111+
</div>
112+
</Link>
69113
<div style={buttonContainerStyle}>
70-
<button style={buttonStyle}>Share</button>
114+
<button style={buttonStyle} onClick={handlePublish}>
115+
Publish
116+
</button>
71117
<NewExportButton />
72118
<Button
73119
style={moreVertButtonStyle}
@@ -83,6 +129,15 @@ const NavBar = () => {
83129
style={{ color: 'white' }}
84130
/>
85131
</div>
132+
<PublishModal
133+
open={publishModalOpen}
134+
onClose={() => setPublishModalOpen(false)}
135+
onSave={handlePublish}
136+
projectName={projectName}
137+
onChange={(e) => setProjectName(e.target.value)}
138+
invalidProjectName={invalidProjectName}
139+
invalidProjectNameMessage={invalidProjectNameMessage}
140+
/>
86141
</nav>
87142
);
88143
};

app/src/components/top/NavBarButtons.tsx

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { useDispatch, useSelector } from 'react-redux';
2-
32
import { Button } from '@mui/material';
43
import DeleteProjects from '../right/DeleteProjects';
54
import ExportButton from '../right/ExportButton';
@@ -8,11 +7,10 @@ import List from '@mui/material/List';
87
import ListItem from '@mui/material/ListItem';
98
import ListItemText from '@mui/material/ListItemText';
109
import LoginButton from '../right/LoginButton';
11-
import MarketplaceButton from '../right/MarketplaceButton';
1210
import Menu from '@mui/material/Menu';
1311
import MenuItem from '@mui/material/MenuItem';
1412
import ProjectsFolder from '../right/OpenProjects';
15-
import React from 'react';
13+
import React, { useEffect, useRef } from 'react';
1614
import { RootState } from '../../redux/store';
1715
import SaveProjectButton from '../right/SaveProjectButton';
1816
import { allCooperativeState } from '../../redux/reducers/slice/appStateSlice';
@@ -185,6 +183,8 @@ const StyledMenuItem = withStyles((theme) => ({
185183
// where the main function starts //
186184
function navbarDropDown(props) {
187185
const dispatch = useDispatch();
186+
187+
188188
const [modal, setModal] = React.useState(null);
189189
const [anchorEl, setAnchorEl] = React.useState(null);
190190
const [roomCode, setRoomCode] = React.useState('');
@@ -201,6 +201,9 @@ function navbarDropDown(props) {
201201
setAnchorEl(event.currentTarget);
202202
};
203203

204+
205+
206+
204207
const clearWorkspace = () => {
205208
// Reset state for project to initial state
206209
const resetState = () => {
@@ -292,10 +295,35 @@ function navbarDropDown(props) {
292295
</svg>
293296
);
294297

295-
const showMenu = props.dropMenu ? 'navDropDown' : 'hideNavDropDown';
298+
let showMenu = props.dropMenu ? 'navDropDown' : 'hideNavDropDown';
299+
300+
//for closing the menu on clicks outside of it.
301+
const useOutsideClick = (callback) => {
302+
303+
const dropdownRef = useRef(null);
304+
305+
useEffect(() => {
306+
const handleClick = (event) => {
307+
if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
308+
callback();
309+
}
310+
}
311+
document.addEventListener('click', handleClick, true);
312+
313+
return () => {
314+
document.removeEventListener('click', handleClick, true);//cleanup for memory purposes. ensures handleclick isn't called after the component is no longer rendered
315+
};
316+
}, [dropdownRef]);
317+
318+
return dropdownRef
319+
320+
}
321+
322+
const ref = useOutsideClick(handleClose);
296323

297324
return (
298-
<div className={showMenu}>
325+
// <div ref={dropdownRef} className={showMenu}> dropdownRef making the menu fly off and anchorel messingup
326+
<div ref={ref} className={showMenu}>
299327
<Link to="/tutorial" style={{ textDecoration: 'none' }} target="_blank">
300328
<button>
301329
Tutorial
@@ -357,7 +385,7 @@ function navbarDropDown(props) {
357385
></input>
358386
<button onClick={() => joinRoom()}>Join Room</button>
359387
<p>In Room: {joinedRoom}</p>
360-
<Link to="/marketplace" style={{ textDecoration: 'none' }} target="_blank">
388+
<Link to="/marketplace" style={{ textDecoration: 'none' }}>
361389
<button>
362390
Marketplace
363391
<svg
@@ -399,4 +427,4 @@ function navbarDropDown(props) {
399427
);
400428
}
401429

402-
export default navbarDropDown;
430+
export default navbarDropDown;

0 commit comments

Comments
 (0)