Skip to content

Commit 547663f

Browse files
committed
Merge branch 'api-gateway-service-and-dockerize' of https://github.com/CS3219-AY2324S1/ay2324s1-course-assessment-g14 into api-gateway-service-and-dockerize
2 parents 4ebffb7 + 586f006 commit 547663f

File tree

13 files changed

+313
-10
lines changed

13 files changed

+313
-10
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,6 @@
3939
npm-debug.log*
4040
yarn-debug.log*
4141
yarn-error.log*
42+
43+
# IDE files
44+
/*/.idea/
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
"use strict";
2+
Object.defineProperty(exports, "__esModule", { value: true });
3+
exports.firebaseConfig = void 0;
4+
require("dotenv/config");
5+
exports.firebaseConfig = {
6+
apiKey: process.env.FIREBASE_API_KEY,
7+
authDomain: "peerprep-d7af2.firebaseapp.com",
8+
projectId: "peerprep-d7af2",
9+
storageBucket: "peerprep-d7af2.appspot.com",
10+
messagingSenderId: "852795173750",
11+
appId: "1:852795173750:web:b1aed6d65dc6d4cb566857",
12+
measurementId: "G-NZSVYREFLC",
13+
};
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
"use strict";
2+
var __importDefault = (this && this.__importDefault) || function (mod) {
3+
return (mod && mod.__esModule) ? mod : { "default": mod };
4+
};
5+
Object.defineProperty(exports, "__esModule", { value: true });
6+
const express_1 = __importDefault(require("express"));
7+
const cors_1 = __importDefault(require("cors"));
8+
const question_controller_1 = require("./question/question.controller");
9+
const app = (0, express_1.default)();
10+
const port = 3002;
11+
app.use((0, cors_1.default)());
12+
app.use(express_1.default.json());
13+
app.get("/", (req, res) => {
14+
res.send("Hello World!");
15+
});
16+
app.get("/questions", question_controller_1.handleGetQuestions);
17+
app.post("/questions", question_controller_1.handleAddQuestion);
18+
app.delete("/questions/:questionId", question_controller_1.handleDeleteQuestion);
19+
app.listen(port, () => {
20+
console.log(`Question Service listening on port ${port}`);
21+
});
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
"use strict";
2+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4+
return new (P || (P = Promise))(function (resolve, reject) {
5+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8+
step((generator = generator.apply(thisArg, _arguments || [])).next());
9+
});
10+
};
11+
Object.defineProperty(exports, "__esModule", { value: true });
12+
exports.handleAddQuestion = exports.handleDeleteQuestion = exports.handleGetQuestions = void 0;
13+
const question_service_1 = require("./question.service");
14+
const firestore_1 = require("firebase/firestore");
15+
function handleGetQuestions(req, res) {
16+
return __awaiter(this, void 0, void 0, function* () {
17+
try {
18+
// console.log(req.query.email);
19+
// const { email } = req.query;
20+
const query = yield (0, firestore_1.getDocs)((0, firestore_1.collection)(question_service_1.db, "questions"));
21+
const result = yield Promise.all(query.docs.map((d) => __awaiter(this, void 0, void 0, function* () {
22+
const q = d.data();
23+
const examplesArray = yield getExamples(d.id);
24+
return {
25+
id: d.id,
26+
title: q.title,
27+
tags: q.tags,
28+
categories: q.categories,
29+
constraints: q.constraints,
30+
difficulty: q.difficulty,
31+
description: q.description,
32+
examples: examplesArray,
33+
};
34+
})));
35+
if (result.length > 0) {
36+
res.status(200).send(result);
37+
}
38+
else {
39+
res.status(500).send("no questions");
40+
}
41+
}
42+
catch (error) {
43+
console.error(error);
44+
res.status(500).send(error);
45+
}
46+
});
47+
}
48+
exports.handleGetQuestions = handleGetQuestions;
49+
const getExamples = (id) => __awaiter(void 0, void 0, void 0, function* () {
50+
const subCollRef = (0, firestore_1.collection)(question_service_1.db, "questions", id, "examples");
51+
const examplesSnapshot = yield (0, firestore_1.getDocs)(subCollRef);
52+
const examplesResult = examplesSnapshot.docs.map((data) => {
53+
const exampleData = data.data();
54+
return {
55+
text: exampleData.text,
56+
image: exampleData.img || "", // Use an empty string if image is missing
57+
};
58+
});
59+
// console.log(examplesSnapshot)
60+
return examplesResult;
61+
});
62+
function handleDeleteQuestion(req, res) {
63+
return __awaiter(this, void 0, void 0, function* () {
64+
const questionId = req.params.questionId;
65+
try {
66+
const docRef = (0, firestore_1.doc)(question_service_1.db, "questions", questionId);
67+
const result = yield (0, firestore_1.deleteDoc)(docRef);
68+
}
69+
catch (err) {
70+
console.log(`error when deleting question with id ${questionId}` + err);
71+
res.status(500).send(err);
72+
}
73+
});
74+
}
75+
exports.handleDeleteQuestion = handleDeleteQuestion;
76+
function handleAddQuestion(req, res) {
77+
return __awaiter(this, void 0, void 0, function* () {
78+
try {
79+
const { qtitle, qtags, qcategories, qconstraints, qdifficulty, qdescription, qexamples, } = req.body;
80+
const docRef = yield (0, firestore_1.addDoc)((0, firestore_1.collection)(question_service_1.db, "questions"), {
81+
title: qtitle,
82+
tags: qtags,
83+
categories: qcategories,
84+
constraints: qconstraints,
85+
difficulty: qdifficulty,
86+
description: qdescription,
87+
});
88+
const exampleRef = (0, firestore_1.collection)(docRef, "examples");
89+
qexamples.map((e) => {
90+
const add = (0, firestore_1.addDoc)(exampleRef, e);
91+
});
92+
// const addExample = setDoc(exampleRef, qexamples)
93+
}
94+
catch (err) {
95+
console.log(err);
96+
res.status(500).send(err);
97+
}
98+
});
99+
}
100+
exports.handleAddQuestion = handleAddQuestion;
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
"use strict";
2+
Object.defineProperty(exports, "__esModule", { value: true });
3+
exports.db = void 0;
4+
const app_1 = require("firebase/app");
5+
const firestore_1 = require("firebase/firestore");
6+
const firebase_config_1 = require("../firebase/firebase.config");
7+
(0, app_1.initializeApp)(firebase_config_1.firebaseConfig);
8+
exports.db = (0, firestore_1.getFirestore)();
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
"use strict";
2+
Object.defineProperty(exports, "__esModule", { value: true });
3+
exports.firebaseConfig = void 0;
4+
require("dotenv/config");
5+
exports.firebaseConfig = {
6+
apiKey: process.env.FIREBASE_API_KEY,
7+
authDomain: "peerprep-d7af2.firebaseapp.com",
8+
projectId: "peerprep-d7af2",
9+
storageBucket: "peerprep-d7af2.appspot.com",
10+
messagingSenderId: "852795173750",
11+
appId: "1:852795173750:web:b1aed6d65dc6d4cb566857",
12+
measurementId: "G-NZSVYREFLC",
13+
};
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
"use strict";
2+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4+
return new (P || (P = Promise))(function (resolve, reject) {
5+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8+
step((generator = generator.apply(thisArg, _arguments || [])).next());
9+
});
10+
};
11+
Object.defineProperty(exports, "__esModule", { value: true });
12+
exports.handleAddQuestion = exports.handleDeleteQuestion = exports.handleGetQuestions = void 0;
13+
const question_service_1 = require("./question.service");
14+
const firestore_1 = require("firebase/firestore");
15+
function handleGetQuestions(req, res) {
16+
return __awaiter(this, void 0, void 0, function* () {
17+
try {
18+
// console.log(req.query.email);
19+
// const { email } = req.query;
20+
console.log(`getting all questions`);
21+
const query = yield (0, firestore_1.getDocs)((0, firestore_1.collection)(question_service_1.db, "questions"));
22+
const result = yield Promise.all(query.docs.map((d) => __awaiter(this, void 0, void 0, function* () {
23+
const q = d.data();
24+
const examplesArray = yield getExamples(d.id);
25+
return {
26+
id: d.id,
27+
title: q.title,
28+
tags: q.tags,
29+
categories: q.categories,
30+
constraints: q.constraints,
31+
difficulty: q.difficulty,
32+
description: q.description,
33+
examples: examplesArray,
34+
};
35+
})));
36+
if (result.length > 0) {
37+
res.status(200).send(result);
38+
}
39+
else {
40+
res.status(500).send("no questions");
41+
}
42+
}
43+
catch (error) {
44+
console.error(error);
45+
res.status(500).send(error);
46+
}
47+
});
48+
}
49+
exports.handleGetQuestions = handleGetQuestions;
50+
const getExamples = (id) => __awaiter(void 0, void 0, void 0, function* () {
51+
const subCollRef = (0, firestore_1.collection)(question_service_1.db, "questions", id, "examples");
52+
const examplesSnapshot = yield (0, firestore_1.getDocs)(subCollRef);
53+
const examplesResult = examplesSnapshot.docs.map((data) => {
54+
const exampleData = data.data();
55+
return {
56+
text: exampleData.text,
57+
image: exampleData.img || "", // Use an empty string if image is missing
58+
};
59+
});
60+
// console.log(examplesSnapshot)
61+
return examplesResult;
62+
});
63+
function handleDeleteQuestion(req, res) {
64+
return __awaiter(this, void 0, void 0, function* () {
65+
const questionId = req.params.questionId;
66+
try {
67+
const docRef = (0, firestore_1.doc)(question_service_1.db, "questions", questionId);
68+
const result = yield (0, firestore_1.deleteDoc)(docRef);
69+
}
70+
catch (err) {
71+
console.log(`error when deleting question with id ${questionId}` + err);
72+
res.status(500).send(err);
73+
}
74+
});
75+
}
76+
exports.handleDeleteQuestion = handleDeleteQuestion;
77+
function handleAddQuestion(req, res) {
78+
return __awaiter(this, void 0, void 0, function* () {
79+
try {
80+
const { qtitle, qtags, qcategories, qconstraints, qdifficulty, qdescription, qexamples, } = req.body;
81+
const docRef = yield (0, firestore_1.addDoc)((0, firestore_1.collection)(question_service_1.db, "questions"), {
82+
title: qtitle,
83+
tags: qtags,
84+
categories: qcategories,
85+
constraints: qconstraints,
86+
difficulty: qdifficulty,
87+
description: qdescription,
88+
});
89+
const exampleRef = (0, firestore_1.collection)(docRef, "examples");
90+
qexamples.map((e) => {
91+
const add = (0, firestore_1.addDoc)(exampleRef, e);
92+
});
93+
// const addExample = setDoc(exampleRef, qexamples)
94+
}
95+
catch (err) {
96+
console.log(err);
97+
res.status(500).send(err);
98+
}
99+
});
100+
}
101+
exports.handleAddQuestion = handleAddQuestion;
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
"use strict";
2+
Object.defineProperty(exports, "__esModule", { value: true });
3+
exports.db = void 0;
4+
const app_1 = require("firebase/app");
5+
const firestore_1 = require("firebase/firestore");
6+
const firebase_config_1 = require("../firebase/firebase.config");
7+
(0, app_1.initializeApp)(firebase_config_1.firebaseConfig);
8+
exports.db = (0, firestore_1.getFirestore)();
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { ReactNode } from "react";
2+
import { Navigate } from "react-router-dom";
3+
import { useAuth } from "./auth.context";
4+
5+
interface RedirectIfLoggedInProps {
6+
children: ReactNode;
7+
}
8+
9+
export default function RedirectIfLoggedIn({ children }: RedirectIfLoggedInProps) {
10+
const { user } = useAuth();
11+
if (user) {
12+
return <Navigate to="/home" />;
13+
}
14+
return <>{children}</>;
15+
}

frontend/src/components/Navbar.tsx

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import AdbIcon from "@mui/icons-material/Adb";
1717
import { useAuth } from "../auth/auth.context";
1818
import { useNavigate } from "react-router-dom";
1919

20-
const pages = ["Products", "Pricing", "Blog"];
20+
const pages = ["Questions"];
2121
const authPages = [
2222
{
2323
name: "Login",
@@ -67,7 +67,7 @@ export default function Navbar() {
6767
variant="h6"
6868
noWrap
6969
component="a"
70-
href="/"
70+
href="/home"
7171
sx={{
7272
mr: 2,
7373
display: { xs: "none", md: "flex" },
@@ -78,7 +78,7 @@ export default function Navbar() {
7878
textDecoration: "none",
7979
}}
8080
>
81-
LOGO
81+
PeerPrep
8282
</Typography>
8383

8484
<Box sx={{ flexGrow: 1, display: { xs: "flex", md: "none" } }}>
@@ -110,12 +110,12 @@ export default function Navbar() {
110110
display: { xs: "block", md: "none" },
111111
}}
112112
>
113-
{pages.map((page) => (
113+
{user && pages.map((page) => (
114114
<MenuItem key={page} onClick={handleCloseNavMenu}>
115115
<Typography textAlign="center">{page}</Typography>
116116
</MenuItem>
117117
))}
118-
{authPages.map((page) => (
118+
{!user && authPages.map((page) => (
119119
<MenuItem key={page.name} onClick={() => navigate(page.link)}>
120120
<Typography textAlign="center">{page.name}</Typography>
121121
</MenuItem>
@@ -127,7 +127,7 @@ export default function Navbar() {
127127
variant="h5"
128128
noWrap
129129
component="a"
130-
href="/"
130+
href="/home"
131131
sx={{
132132
mr: 2,
133133
display: { xs: "flex", md: "none" },
@@ -139,10 +139,10 @@ export default function Navbar() {
139139
textDecoration: "none",
140140
}}
141141
>
142-
LOGO
142+
PeerPrep
143143
</Typography>
144144
<Box sx={{ flexGrow: 1, display: { xs: "none", md: "flex" } }}>
145-
{pages.map((page) => (
145+
{user && pages.map((page) => (
146146
<Button
147147
key={page}
148148
onClick={handleCloseNavMenu}

0 commit comments

Comments
 (0)