Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add User profile with edit profile option #8

Merged
merged 12 commits into from
Feb 28, 2024
77 changes: 77 additions & 0 deletions backend/src/routes/user.route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ import { Router } from "express";
import { HttpCodes } from "../types/HttpCodes";
import { CustomResponse } from "../types/CustomResponse";
import { newUser } from "../service/user.service";
import { updateUser } from "../service/user.service";
import { getUserByEmail } from "../service/user.service";
import { User } from "@prisma/client";

export const userRouter = Router();

userRouter.post("/create", async (req, res) => {
Expand Down Expand Up @@ -29,3 +33,76 @@ userRouter.post("/create", async (req, res) => {
return res.status(HttpCodes.CREATED).json(response);
});

userRouter.get("/get", async (req, res) => {
try {
const userEmail = req.session.email as string;
const userDataResponse = await getUserByEmail(userEmail);

if (userDataResponse.error) {
throw new Error("Failed to fetch user data");
}

const userData = userDataResponse.data as User;

const response: CustomResponse = {
error: false,
message: "User data fetched successfully",
data: {
email: userData.email,
phoneNumber: userData.phoneNumber,
name: userData.name
}
};

return res.status(HttpCodes.OK).json(response);
} catch (error) {
console.error("Error fetching user data:", error);

const response: CustomResponse = {
error: true,
message: "Failed to fetch user data",
data: null
};

return res.status(HttpCodes.INTERNAL_SERVER_ERROR).json(response);
}
});


userRouter.post("/update", async (req, res) => {
try {
const data = req.body;
const email = req.session.email as string;

data["email"] = email;
const updateUserResponse = await updateUser(data);

if (updateUserResponse.error) {
const response: CustomResponse = {
error: true,
message: updateUserResponse.data as string,
data: null
}
return res.status(HttpCodes.INTERNAL_SERVER_ERROR).json(response);
}

const response: CustomResponse = {
error: false,
message: "User Updated successfully",
data: updateUserResponse.data
}

return res.status(HttpCodes.OK).json(response);
} catch (error) {
console.error("Error updating user data:", error);

const response = {
error: true,
message: "Failed to update user data",
data: null
};

return res.status(HttpCodes.INTERNAL_SERVER_ERROR).json(response);
}
});

74 changes: 73 additions & 1 deletion backend/src/service/user.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,76 @@ export const newUser = async (user: {
data: null
}
}
}
}

export const updateUser = async (user: {
name: string,
email: string,
phoneNumber: string,
}): Promise<CustomReturn<User>> => {
if (!user.name || !user.phoneNumber) {
return {
error: true,
data: "Name and Phone Number are required to update the profile."
};
}

try {
let userdetail = await prisma.user.findUnique({
where: {
email: user.email
}
});

if (!userdetail) return {
error: true,
data: "User does not exist."
}

let updatedUser = await prisma.user.update({
where: { email: user.email },
data: {
name: user.name,
phoneNumber: user.phoneNumber,
},
});

return {
error: false,
data: updatedUser
};
} catch (error) {
console.error("Error updating user:", error);

return {
error: true,
data: null
};
}
};


export const getUserByEmail = async (email: string): Promise<CustomReturn<User>> => {
try {
let user = await prisma.user.findUnique({
where: {
email: email
}
});

if (!user) return {
error: true,
data: "User does not exist."
}

return {
error: false,
data: user
}
} catch (error) {
return {
error: true,
data: null
}
}
}
115 changes: 112 additions & 3 deletions backend/tests/user.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { describe, expect } from "@jest/globals";
import { prismaMock } from "./_mockdb";
import { newUser } from "../src/service/user.service";

import { getUserByEmail, newUser } from "../src/service/user.service";
import { updateUser } from "../src/service/user.service";

describe("Create a new user", () => {
it("should create a new user", () => {
Expand Down Expand Up @@ -71,4 +71,113 @@ describe("Create a new user", () => {
data: "Phone Number is required to create profile."
});
})
})

it("should check if user already exists", () => {
const user = {
id: "1",
name: "name",
email: "email",
phoneNumber: "phoneNumber",
karmaPoints: 0

}

prismaMock.user.create.mockRejectedValue(new Error("User already exists."));
expect(newUser(user)).resolves.toEqual({
error: true,
data: null
});
})
});

describe("Update user profile", () => {
it("should return an error if name is not given", () => {
const user = {
id: "1",
name: "",
email: "email",
phoneNumber: "phoneNumber",
karmaPoints: 0
};

expect(updateUser(user)).resolves.toEqual({
error: true,
data: "Name and Phone Number are required to update the profile."
});
});

it("should return an error if name is not given", () => {
const user = {
id: "1",
name: "name",
email: "email",
phoneNumber: "",
karmaPoints: 0
};

expect(updateUser(user)).resolves.toEqual({
error: true,
data: "Name and Phone Number are required to update the profile."
});
});

it("should update user name and phone successfully", () => {
const user = {
id: "1",
name: "NewName",
email: "email",
phoneNumber: "newPhoneNumber",
karmaPoints: 0
};
prismaMock.user.findUnique.mockResolvedValue({
id: "1",
name: "OldName",
email: "email",
phoneNumber: "oldPhoneNumber",
karmaPoints: 0
});

prismaMock.user.update.mockResolvedValue(user);

expect(updateUser(user)).resolves.toEqual({
error: false,
data: user
});
});
});

describe ("Fetch user data", () => {
it("should fetch user data", () => {
const user = {
id: "1",
name: "name",
email: "email",
phoneNumber: "phoneNumber",
karmaPoints: 0
};

prismaMock.user.findUnique.mockResolvedValue(user);

expect(getUserByEmail(user.email)).resolves.toEqual({
error: false,
data: user
});
});

it("should return an error if user does not exist", () => {
const user = {
id: "1",
name: "name",
email: "email",
phoneNumber: "phoneNumber",
karmaPoints: 0
};

prismaMock.user.findUnique.mockResolvedValue(null);

expect(getUserByEmail(user.email)).resolves.toEqual({
error: true,
data: "User does not exist."
});
});
});
10 changes: 10 additions & 0 deletions frontend/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,16 @@ export default function Home() {
Create a Post
</Button>
</div>
<div className="flex flex-wrap gap-4 justify-center items-center">
<Button color="success" variant="bordered" radius="sm" size="lg"
onClick={
() => {
window.location.href = "/user/dashboard";
}
}>
My Profile
</Button>
</div>
<div
className="grid md:grid-cols-3 gap-4 m-4">
{
Expand Down
Loading
Loading