-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathserver.js
337 lines (283 loc) · 10.7 KB
/
server.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
const express = require('express');
const mysql = require('mysql2/promise');
const cors = require('cors');
const bcrypt = require('bcrypt');
const app = express();
app.use(cors());
app.use(express.json());
async function createConnection() {
// Create connection
const db = await mysql.createConnection({
host: '127.0.0.1',
user: 'root',
password: 'B@hsir6113',
database: 'green_commute'
});
console.log('MySQL connected...');
return db;
}
app.listen('3000', () => {
console.log('Server started on port 3000');
});
// Get challenges
app.get('/challenges', async (req, res) => {
try {
const dbInstance = await createConnection();
let sql = 'SELECT * FROM challenges';
const [results] = await dbInstance.query(sql);
console.log("Challenges fetched...");
res.send(results);
} catch (err) {
console.error(err);
res.status(500).send('Server error');
}
});
// Get leaderboard
app.get('/leaderboard', async (req, res) => {
try {
const dbInstance = await createConnection();
let sql = `
SELECT lb.*, u.UserName
FROM overallleaderboard AS lb
INNER JOIN users AS u ON lb.UserID = u.UserID
`;
const [results] = await dbInstance.query(sql);
console.log("Leaderboard data fetched...");
res.send(results);
} catch (err) {
console.error(err);
res.status(500).send('Server error');
}
});
// Get achievements for a specific user
app.get('/achievements/:userId', async (req, res) => {
try {
const userId = req.params.userId;
const dbInstance = await createConnection();
let sql = 'SELECT * FROM userbadge WHERE UserID = ?';
const [results] = await dbInstance.query(sql, [userId]);
console.log(`Achievements fetched for user ${userId}`);
res.send(results);
} catch (err) {
console.error(err);
res.status(500).send('Server error');
}
});
// Signup
app.post('/signup', async (req, res) => {
const { UserName, FirstName, LastName, Email, Password } = req.body;
if (!UserName || !FirstName || !LastName || !Email || !Password) {
return res.status(400).send('Please provide all required fields');
}
try {
// Get database connection from the pool
const db = await createConnection();
// Check if the user already exists
const [existingUser] = await db.query('SELECT * FROM users WHERE UserName = ?', [UserName]);
if (existingUser.length > 0) {
// User exists, send a 409 Conflict response
return res.status(409).json({ message: 'Username already exists' });
}
// Hash the password
const hashedPassword = await bcrypt.hash(Password, 10);
const newUser = [UserName, FirstName, LastName, Email, hashedPassword];
const sql = 'INSERT INTO users (UserName, FirstName, LastName, Email, Password) VALUES (?)';
db.query(sql, [newUser])
.then(result => {
console.log('User added to database');
res.send('User added to database');
})
.catch(err => {
console.error(err);
res.status(500).send('Server error');
});
} catch (error) {
console.error(error);
res.status(500).send('Server error');
}
});
// Get a specific user by ID
app.get('/users/:id', async (req, res) => {
let sql = 'SELECT UserName, FirstName, LastName, Email FROM users WHERE UserID = ?';
db.query(sql, [req.params.id], (err, results) => {
if(err) throw err;
console.log(`User ${req.params.id} fetched...`);
res.send(results);
});
});
// Get a specific challenge by ID
app.get('/challenges/:id', async (req, res) => {
try {
// Ensure the database connection is established before querying
const dbInstance = await createConnection();
let sql = 'SELECT ChallengeName, Description FROM challenges WHERE ChallengeID = ?';
const [results] = await dbInstance.query(sql, [req.params.id]);
console.log(`Challenge ${req.params.id} fetched...`);
res.send(results);
} catch (err) {
console.error(err);
res.status(500).send('Server error');
}
});
// Login
app.post('/login', async (req, res) => {
const { Email, Password } = req.body;
if (!Email || !Password) {
return res.status(400).send('Please provide email and password');
}
try {
// Get database connection from the pool
const dbInstance = await createConnection();
// Check if the user exists
const [user] = await dbInstance.query('SELECT * FROM users WHERE Email = ?', [Email]);
if (user.length > 0) {
// User exists, check password
const match = await bcrypt.compare(Password, user[0].Password);
if (match) {
// Passwords match, send a 200 OK response with user data
console.log('Login successful');
const { UserName, FirstName, LastName, Email, UserID } = user[0]; // Destructure user object
console.log(user);
return res.status(200).json({ UserName, FirstName, LastName, Email, UserID }); // Send user data with corrected property names
} else {
// Passwords do not match, send a 401 Unauthorized response
return res.status(401).json({ message: 'Invalid password' });
}
} else {
// User does not exist, send a 404 Not Found response
return res.status(404).json({ message: 'User not found' });
}
} catch (error) {
console.error(error);
res.status(500).send('Server error');
}
});
// Server-side route to delete user
app.delete('/users/:id', async (req, res) => {
try {
const dbInstance = await createConnection();
const userId = req.params.id;
// Delete the user from the database
await dbInstance.query('DELETE FROM users WHERE UserID = ?', [userId]);
console.log(`User with ID ${userId} deleted`);
res.status(200).send('User deleted successfully');
} catch (error) {
console.error(error);
res.status(500).send('Server error');
}
});
// Route to handle updating EcoPoints when a button is clicked
app.post('/completeTrip/:userID', async (req, res) => {
const userID = req.params.userID;
try {
const connection = await createConnection();
// Call the stored procedure to update EcoPoints for the user
await connection.query('CALL UpdateEcoPoints(?)', [userID]);
connection.end(); // Close the connection after executing the query
console.log(`EcoPoints updated for user with ID ${userID}`);
res.status(200).send('EcoPoints updated successfully');
} catch (error) {
console.error(error);
res.status(500).send('Server error');
}
});
// Route to join a challenge
app.post('/joinChallenge', async (req, res) => {
try {
const { ChallengeID, UserID } = req.body;
console.log('Received join challenge request:', req.body); // Log the received data
const dbInstance = await createConnection();
// Insert the ChallengeID and UserID into the trips table
const sqlInsertTrip = 'INSERT INTO trips (ChallengeID, UserID) VALUES (?, ?);';
await dbInstance.query(sqlInsertTrip, [ChallengeID, UserID]);
// Check if the user already exists in the overallleaderboard
const sqlCheckUser = 'SELECT * FROM overallleaderboard WHERE UserID = ?;';
const [userRows] = await dbInstance.query(sqlCheckUser, [UserID]);
// If the user doesn't exist in the overallleaderboard, insert them with TotalEcoPoints set to 0
if (userRows.length === 0) {
const sqlInsertUser = 'INSERT INTO overallleaderboard (UserID, TotalEcoPoints) VALUES (?, 0);';
await dbInstance.query(sqlInsertUser, [UserID]);
}
console.log(`User with ID ${UserID} joined challenge with ID ${ChallengeID}`);
res.status(200).send('User joined challenge successfully');
} catch (error) {
console.error('Error joining challenge:', error); // Log any errors that occur
res.status(500).send('Server error');
}
});
app.post('/completeChallenge', async (req, res) => {
let dbInstance; // Declare dbInstance outside the try-catch block
try {
const { UserID, ChallengeID } = req.body;
dbInstance = await createConnection(); // Initialize dbInstance
console.log(UserID, ChallengeID);
await dbInstance.beginTransaction(); // Begin transaction
// Update TripCompleted value to 1 (completed) for the specific challenge and user
const updateTripSql = 'UPDATE trips SET TripCompleted = 1 WHERE UserID = ? AND ChallengeID = ?';
await dbInstance.query(updateTripSql, [UserID, ChallengeID]);
// Fetch BadgeID from challenges table based on ChallengeID
const [challengeResult] = await dbInstance.query('SELECT BadgeID FROM challenges WHERE ChallengeID = ?', [ChallengeID]);
const BadgeID = challengeResult[0].BadgeID;
// Execute stored procedure to update leaderboard
const updateSql = 'CALL UpdateOverallLeaderboard(?)';
await dbInstance.query(updateSql, [UserID]); // Call stored procedure with UserID
// Insert badge into userbadge table
const insertBadgeSql = 'INSERT INTO userbadge (UserID, BadgeID) VALUES (?, ?)';
await dbInstance.query(insertBadgeSql, [UserID, BadgeID]);
// Commit transaction
await dbInstance.commit();
console.log(`Challenge ${ChallengeID} completed for user with ID ${UserID}`);
res.status(200).send('Challenge marked as completed successfully');
} catch (error) {
// Rollback transaction on error
if (dbInstance) {
await dbInstance.rollback();
}
console.error(error);
res.status(500).send('Server error');
}
});
// Get challenges for a specific user
app.get('/userChallenges', async (req, res) => {
try {
const { UserID } = req.query;
const dbInstance = await createConnection();
let sql = `
SELECT c.*, t.TripCompleted
FROM challenges c
INNER JOIN trips t ON c.ChallengeID = t.ChallengeID
WHERE t.UserID = ?
`;
const [results] = await dbInstance.query(sql, [UserID]);
console.log(`Challenges fetched for user ${UserID}`);
// Check TripCompleted value and update completed flag accordingly
const challenges = results.map(challenge => ({
...challenge,
completed: challenge.TripCompleted === 1
}));
res.send(challenges);
} catch (err) {
console.error(err);
res.status(500).send('Server error');
}
});
// Get achievements for a specific user
app.get('/userbadge/:userId', async (req, res) => {
try {
const userId = req.params.userId;
const dbInstance = await createConnection();
let sql = `
SELECT b.BadgeName, b.Description
FROM userbadge ub
INNER JOIN badges b ON ub.BadgeID = b.BadgeID
WHERE ub.UserID = ?
`;
const [results] = await dbInstance.query(sql, [userId]);
console.log(results);
console.log(`Achievements fetched for user ${userId}`);
res.send(results);
} catch (err) {
console.error(err);
res.status(500).send('Server error');
}
});