Skip to content

Commit e11a0e4

Browse files
committed
Project Editing
2 parents 0ddeb5a + 549e4e5 commit e11a0e4

File tree

6 files changed

+73
-2
lines changed

6 files changed

+73
-2
lines changed

app/src/components/marketplace/MarketplaceCard.tsx

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,13 @@ import { MoreVert } from '@mui/icons-material';
1717
import React from 'react';
1818
import imageSrc from '../../../../resources/marketplace_images/marketplace_image.png';
1919
import { red } from '@mui/material/colors';
20+
import axios from 'axios';
2021
import {useDispatch, useSelector} from 'react-redux'
2122
import { RootState } from '../../redux/store';
2223
import { saveProject } from '../../helperFunctions/projectGetSaveDel';
2324

2425
interface Project {
26+
forked: String,
2527
comments: string[]
2628
createdAt: Date
2729
likes: number
@@ -42,6 +44,15 @@ const MarketplaceCard = ({proj} :{proj: Project}) => {
4244
const handleClick = (event: React.MouseEvent<HTMLElement>) => {
4345
setAnchorEl(event.currentTarget);
4446
};
47+
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+
});
53+
alert('Project cloned!');
54+
setAnchorEl(null);
55+
};
4556
const handleClose = () => {
4657
setAnchorEl(null);
4758
};
@@ -97,7 +108,7 @@ const MarketplaceCard = ({proj} :{proj: Project}) => {
97108
}}
98109
>
99110
<MenuItem
100-
onClick={handleClose}
111+
onClick={handleClone}
101112
sx={{
102113
color: '#C6C6C6'
103114
}}

server/controllers/cookieController.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,18 @@ const cookieController: CookieController = {
1010
secure: true
1111
});
1212
return next();
13+
},
14+
15+
/**
16+
* Stores the current user's username in cookie (for use in cloning projects)
17+
*/
18+
setUserCookie: (req, res, next) => {
19+
res.cookie('username', res.locals.username, {
20+
httpOnly: true,
21+
sameSite: 'none',
22+
secure: true
23+
});
24+
return next();
1325
}
1426
};
1527

server/controllers/marketplaceController.ts

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,39 @@ const marketplaceController: MarketplaceController = {
102102
})
103103

104104
}
105-
}
105+
},
106+
107+
/**
108+
* Middleware function that clones and saves project to user's library
109+
*
110+
*/
111+
cloneProject: (req, res, next) => {
112+
// pulls cookies from request
113+
const userId = req.cookies.ssid;
114+
const username = req.cookies.username;
115+
const { updatedProject } = req.body;
116+
updatedProject.userId = userId;
117+
updatedProject.username = username;
118+
updatedProject.project.forked = true; // updated the forked tag
119+
delete updatedProject._id; // removes the old project id from the object
120+
updatedProject.createdAt = Date.now();
121+
122+
Projects.create(
123+
// creates a copy of the project to the user's library
124+
updatedProject,
125+
(err, result) => {
126+
if (err) {
127+
return next({
128+
log: `Error in marketplaceController.cloneProject: ${err}`,
129+
message: {
130+
err: 'Error in marketplaceController.cloneProject, check server logs for details'
131+
}
132+
});
133+
}
134+
res.locals.clonedProject = result;
135+
return next();
136+
}
137+
);
138+
},
106139
};
107140
export default marketplaceController;

server/controllers/userController.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,9 @@ const userController: UserController = {
7575
}
7676
// if no error found when creating a new user, send back user ID in res.locals
7777
res.locals.id = newUser.id;
78+
// send back username to store on cookies for forking projects
79+
console.log(username);
80+
res.locals.username = username;
7881
return next();
7982
}
8083
);
@@ -114,6 +117,7 @@ const userController: UserController = {
114117
if (isMatch) {
115118
// if password matches, save user id for following middleware
116119
res.locals.id = user.id;
120+
res.locals.username = username;
117121
return next();
118122
}
119123
// if hashed password is not matched saved password in db, send 400 response

server/interfaces.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { Document, NativeError } from 'mongoose';
33

44
export interface CookieController {
55
setSSIDCookie: RequestHandler;
6+
setUserCookie: RequestHandler;
67
}
78

89
export interface ProjectController {
@@ -15,6 +16,7 @@ export interface MarketplaceController {
1516
publishProject: RequestHandler;
1617
getPublishedProjects: RequestHandler;
1718
unpublishProject: RequestHandler;
19+
cloneProject: RequestHandler;
1820
}
1921

2022
export interface RequestId extends Request {

server/server.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ app.post(
159159
'/signup',
160160
userController.createUser,
161161
cookieController.setSSIDCookie,
162+
cookieController.setUserCookie,
162163
sessionController.startSession,
163164
(req, res) => res.status(200).json({ sessionId: res.locals.ssid })
164165
);
@@ -167,6 +168,7 @@ app.post(
167168
'/login',
168169
userController.verifyUser,
169170
cookieController.setSSIDCookie,
171+
cookieController.setUserCookie,
170172
sessionController.startSession,
171173
(req, res) => res.status(200).json({ sessionId: res.locals.ssid })
172174
);
@@ -217,6 +219,13 @@ app.get(
217219
(req, res) => res.status(200).json(res.locals.publishedProjects)
218220
);
219221

222+
// Clone from marketplace
223+
app.post(
224+
'/cloneProject',
225+
marketplaceController.cloneProject,
226+
(req, res) => res.status(200).json(res.locals.clonedProject)
227+
);
228+
220229
// serve index.html on the route '/'
221230
const isDocker = process.env.IS_DOCKER === 'true';
222231
console.log('this is running on docker: ', isDocker);

0 commit comments

Comments
 (0)