Skip to content

Commit add34a5

Browse files
committed
Merge branch 'dev' into denton/link
2 parents 9f1de2b + 549e4e5 commit add34a5

File tree

9 files changed

+78
-3
lines changed

9 files changed

+78
-3
lines changed

app/src/components/marketplace/MarketplaceCard.tsx

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,10 @@ 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

2122
interface Project {
23+
forked: String,
2224
comments: string[]
2325
createdAt: Date
2426
likes: number
@@ -37,9 +39,19 @@ const MarketplaceCard = ({proj} :{proj: Project}) => {
3739
const handleClick = (event: React.MouseEvent<HTMLElement>) => {
3840
setAnchorEl(event.currentTarget);
3941
};
40-
const handleClose = () => {
42+
const handleClone = async () => { // creates a copy of the project
43+
const updatedProject: Project = JSON.parse(JSON.stringify(proj)); // creates a deep copy
44+
updatedProject.forked = `Forked from ${updatedProject.username}`;
45+
await axios.post('/cloneProject', {
46+
updatedProject
47+
});
48+
alert('Project cloned!');
4149
setAnchorEl(null);
4250
};
51+
const handleClose = () => {
52+
setAnchorEl(null);
53+
}
54+
4355
return (
4456
<>
4557
<Card
@@ -90,7 +102,7 @@ const MarketplaceCard = ({proj} :{proj: Project}) => {
90102
}}
91103
>
92104
<MenuItem
93-
onClick={handleClose}
105+
onClick={handleClone}
94106
sx={{
95107
color: '#C6C6C6'
96108
}}

app/src/interfaces/Interfaces.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { DragObjectWithType } from 'react-dnd';
22

33
export interface State {
44
name: string;
5+
forked: boolean;
56
isLoggedIn: boolean;
67
components: Component[];
78
rootComponents: number[];

app/src/redux/reducers/slice/appStateSlice.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import manageSeparators from '../../../helperFunctions/manageSeparators';
1313

1414
export const initialState: State = {
1515
name: '',
16+
forked: false,
1617
isLoggedIn: false,
1718
// config: { saveFlag: true, saveTimer: false },
1819
components: [

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/models/reactypeModels.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ const sessionSchema = new Schema({
7979
const projectSchema = new Schema(
8080
{
8181
name: String,
82+
forked: String,
8283
likes: { type: Number, default: 0 },
8384
published: { type: Boolean, default: false },
8485
project: { type: Object, required: true },

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)