Skip to content

Commit

Permalink
Merge pull request #74 from CS3219-AY2425S1/frontend_fetch-standardis…
Browse files Browse the repository at this point in the history
…ed-api-responses

fix: Align Frontend with Standardized Backend Response Structure
  • Loading branch information
HollaG authored Oct 12, 2024
2 parents 49ff0db + 88dd97d commit 81859b4
Show file tree
Hide file tree
Showing 8 changed files with 146 additions and 126 deletions.
12 changes: 3 additions & 9 deletions peer-prep/src/hooks/useApi.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,10 @@ import { useLocalStorage } from "@mantine/hooks";
import { useAuth } from "./useAuth";
import { useNavigate } from "react-router-dom";

export interface QuestionServerResponse<T> {
success: boolean;
status: number;
data: T;
message?: string;
}

export interface UserServerResponse<T> {
user?: T;
export interface ServerResponse<T> {
statusCode: number;
message: string;
data: T;
}

// export interface ServerError {
Expand Down
12 changes: 6 additions & 6 deletions peer-prep/src/hooks/useAuth.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { useLocalStorage } from "@mantine/hooks";
import { createContext, ReactElement, useContext, useMemo } from "react";
import { useNavigate } from "react-router-dom";
import { User } from "../types/user";
import useApi, { SERVICE, UserServerResponse } from "./useApi";
import { User, UserResponseData } from "../types/user";
import useApi, { ServerResponse, SERVICE } from "./useApi";
import { notifications } from "@mantine/notifications";

export interface AuthContextType {
Expand Down Expand Up @@ -45,7 +45,7 @@ export const AuthProvider = ({

// call this function when you want to authenticate the user
const login = async (data: { email: string; password: string }) => {
fetchData<UserServerResponse<User>>(
fetchData<ServerResponse<UserResponseData>>(
`/user-service/users/login`,
SERVICE.USER,
{
Expand All @@ -56,10 +56,10 @@ export const AuthProvider = ({
body: JSON.stringify(data),
}
)
.then((data) => {
.then((response) => {
// ok!
setUser(data.user || null);
console.log(data.user, "<<<<");
setUser(response.data.user || null);
console.log(response.data.user, "<<<<");
navigate("/dashboard", { replace: true });

notifications.show({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,21 @@ import ReactQuill from "react-quill";
import "react-quill/dist/quill.snow.css";

import classes from "./CreateQuestionPage.module.css";
import { Question, QuestionOlsd, TestCase } from "../../../types/question";
import useApi, { QuestionServerResponse, SERVICE } from "../../../hooks/useApi";
import { QuestionResponseData, TestCase } from "../../../types/question";
import useApi, { ServerResponse, SERVICE } from "../../../hooks/useApi";
import { notifications } from "@mantine/notifications";
import { useNavigate } from "react-router-dom";

export default function CreateQuestionPage() {
const [name, setName] = useState("");
const [difficulty, setDifficulty] = useState<string | null>("EASY");
const [categories, setCategories] = useState<string[]>([]);
const [description, setDescription] = useState("");
const [testCases, setTestCases] = useState<TestCase[]>([]);
const [solution, setSolution] = useState("");
const [link, setLink] = useState("");

const navigate = useNavigate();

const [fetchedCategories, setFetchedCategories] = useState<
{ value: string; label: string }[]
Expand All @@ -50,27 +55,18 @@ export default function CreateQuestionPage() {

const fetchCategories = async () => {
try {
const response = await fetchData<QuestionServerResponse<string[]>>(
const response = await fetchData<ServerResponse<QuestionResponseData>>(
"/question-service/categories",
SERVICE.QUESTION
);

if (response.success) {
const categories = response.data;
const transformedCategories = categories.map((category: string) => ({
value: category.toUpperCase(),
label:
category.charAt(0).toUpperCase() + category.slice(1).toLowerCase(),
}));
setFetchedCategories(transformedCategories);
} else {
notifications.show({
message:
response.message ||
"Error fetching categories, please try again later.",
color: "red",
});
}
const categories = response.data.categories || [];
const transformedCategories = categories.map((category: string) => ({
value: category.toUpperCase(),
label:
category.charAt(0).toUpperCase() + category.slice(1).toLowerCase(),
}));
setFetchedCategories(transformedCategories);
} catch (error: any) {
console.error("Error fetching categories", error);
notifications.show({
Expand All @@ -89,7 +85,7 @@ export default function CreateQuestionPage() {
}));

try {
const response = await fetchData<QuestionServerResponse<Question>>(
const response = await fetchData<ServerResponse<QuestionResponseData>>(
"/question-service",
SERVICE.QUESTION,
{
Expand All @@ -103,21 +99,19 @@ export default function CreateQuestionPage() {
categories,
difficulty,
testCases: updatedTestCases,
solutionCode: solution,
link,
}),
}
);
notifications.show({
message: "Question created successfully!",
color: "green",
});

if (response.success) {
alert("Question created successfully!");
window.location.href = "/questions";
} else {
notifications.show({
message:
response.message ||
"Error creating question, please try again later.",
color: "red",
});
}
// Redirect to questions page
// todo: redirect to the specific qn page
navigate("/questions", { replace: true });
} catch (error: any) {
console.log("Error creating question:", error);
notifications.show({
Expand Down Expand Up @@ -183,6 +177,14 @@ export default function CreateQuestionPage() {
minRows={8}
required
/>

<Textarea
label={"Solution"}
value={solution}
onChange={(event) => setSolution(event.currentTarget.value)}
minRows={8}
required
/>
{/* <Input.Wrapper label="Description" required>
<ReactQuill
theme="snow"
Expand All @@ -205,6 +207,13 @@ export default function CreateQuestionPage() {
</ReactQuill>
</Input.Wrapper> */}

<TextInput
label="Link to question (e.g. Leetcode)"
value={link}
onChange={(event) => setLink(event.currentTarget.value)}
required
/>

<Flex style={{ alignItems: "baseline", gap: 4 }}>
<Text className={classes.testCaseHeader}>Test Cases</Text>
<Text style={{ color: "red" }}>*</Text>
Expand Down
Loading

0 comments on commit 81859b4

Please sign in to comment.