diff --git a/code/backend/src/controllers/profileController.ts b/code/backend/src/controllers/profileController.ts
index 3ce1644..4f8d017 100644
--- a/code/backend/src/controllers/profileController.ts
+++ b/code/backend/src/controllers/profileController.ts
@@ -202,6 +202,7 @@ export const updateBio = async (req: Request, res: Response) => {
// Endpoint to get user data
export const getProfile = async (req: Request, res: Response) => {
const username: string = req.params.username as string;
+ const requestingUser: JwtPayload | undefined = req.user;
if (!username) {
res.status(StatusCodes.BAD_REQUEST).json({
error: "no username",
@@ -227,9 +228,22 @@ export const getProfile = async (req: Request, res: Response) => {
const publicUser: PublicUser | undefined = await getUser(user.id);
+ let isFollowing : boolean = false;
+ if(requestingUser) {
+ const followingData = await prisma.follow.findFirst({
+ where: {
+ followedUserId: user.id,
+ followingUserId: requestingUser.id,
+ }
+ })
+ if(followingData) {
+ isFollowing = true;
+ }
+ }
+
res.status(StatusCodes.OK).json({
message: "User found",
- data: publicUser,
+ data: {...publicUser, isFollowing},
});
} catch (err) {
console.error(err);
diff --git a/code/backend/src/routes/profileRoutes.ts b/code/backend/src/routes/profileRoutes.ts
index 61ff87a..f1915a7 100644
--- a/code/backend/src/routes/profileRoutes.ts
+++ b/code/backend/src/routes/profileRoutes.ts
@@ -10,6 +10,7 @@ const profileRouter = express.Router();
import { upload } from "../middleware/uploadSingle";
import { updateBioSchema } from "../schemas/profileSchemas";
import { validateData } from "../middleware/validationMiddleware";
+import { optionalAuthenticateToken } from "../middleware/optionalAuthenticateToken";
/**
* @swagger
* /api/profile/uploadProfilePicture:
@@ -124,5 +125,5 @@ profileRouter.put(
* 401:
* description: Ungültige Anmeldedaten
*/
-profileRouter.get("/:username", getProfile);
+profileRouter.get("/:username", optionalAuthenticateToken, getProfile);
export default profileRouter;
diff --git a/code/frontend/src/api/axios.ts b/code/frontend/src/api/axios.ts
index 4deee55..358f9da 100644
--- a/code/frontend/src/api/axios.ts
+++ b/code/frontend/src/api/axios.ts
@@ -10,7 +10,6 @@ const api = axios.create({
// get token from local storage
const getAccessToken = () => localStorage.getItem("token");
-const getRefreshToken = () => localStorage.getItem("refreshToken");
//redirects the page to the login and back
export const redirectToLogin = (returnToPage = true) => {
diff --git a/code/frontend/src/components/ChangeAvatarDialog.tsx b/code/frontend/src/components/ChangeAvatarDialog.tsx
index e7d17ba..bfb1c36 100644
--- a/code/frontend/src/components/ChangeAvatarDialog.tsx
+++ b/code/frontend/src/components/ChangeAvatarDialog.tsx
@@ -87,11 +87,9 @@ export default function AvatarDialog({
- U
+ {username && username[0].toUpperCase() || ""}
diff --git a/code/frontend/src/components/changeAvatarDialog.css b/code/frontend/src/components/changeAvatarDialog.css
index 6f75c41..5f2b68d 100644
--- a/code/frontend/src/components/changeAvatarDialog.css
+++ b/code/frontend/src/components/changeAvatarDialog.css
@@ -19,8 +19,8 @@
}
.profile-avatar {
- width: 40px;
- height: 40px;
+ width: 50px;
+ height: 50px;
background-color: var(--Rotkehlchen-yellow-default);
}
@@ -46,8 +46,8 @@
@media screen and (min-width: 768px) {
.profile-avatar {
- width: 5rem;
- height: 5rem;
+ width: 4.5rem;
+ height: 4.5rem;
background-color: var(--Rotkehlchen-yellow-default);
}
diff --git a/code/frontend/src/components/username.css b/code/frontend/src/components/username.css
index 39650ff..7be6bfb 100644
--- a/code/frontend/src/components/username.css
+++ b/code/frontend/src/components/username.css
@@ -1,10 +1,21 @@
.profile-username {
color: var(--Rotkehlchen-orange-default);
- max-width: 10rem;
+ width: 15rem;
overflow: hidden;
text-overflow: ellipsis;
cursor: pointer;
+ text-align: start;
}
.profile-popover {
padding: 1rem;
}
+
+@media screen and (min-width: 768px) {
+ .profile-username {
+ width: 10rem;
+ }
+ .profile-popover {
+ padding: 2rem;
+ }
+
+}
diff --git a/code/frontend/src/pages/Profile.tsx b/code/frontend/src/pages/Profile.tsx
index b14df9a..eb1cee0 100644
--- a/code/frontend/src/pages/Profile.tsx
+++ b/code/frontend/src/pages/Profile.tsx
@@ -8,7 +8,7 @@ import { StyledEngineProvider, Divider } from "@mui/material";
import ChangeAvatarDialog from "../components/ChangeAvatarDialog";
import Bio from "../components/Bio";
import RotkehlchenButton from "../components/ButtonRotkehlchen";
-import api from "../api/axios";
+import api, { redirectToLogin } from "../api/axios";
import { useAuth } from "../api/Auth";
import { useNavigate, useParams } from "react-router-dom";
import { useEffect, useState } from "react";
@@ -27,11 +27,12 @@ function Profile() {
followers: 0,
following: 0,
posts: 0,
+ isFollowing: false,
});
const userProfile = async () => {
try {
- const response = await api.get(`/profile/get/${username}`);
+ const response = await api.get(`/profile/${username}`);
setUserData(response.data.data);
return;
} catch (error) {
@@ -54,12 +55,20 @@ function Profile() {
return prevData;
});
};
- function handleFollowUser() {
- // TODO: implement follow user functionality
- if (user) {
- api.post(`follower/follow/${username}`)
+ const handleFollowUser = async () => {
+ try {
+ if (userData?.isFollowing === false) {
+ await api.post(`/follower/follow/${username}`);
+ } else if (userData?.isFollowing === true) {
+ await api.delete(`/follower/unfollow/${username}`);
+ } else {
+ redirectToLogin();
+ }
+ userProfile(); // Refresh user data after unfollowing
+ } catch (error) {
+ console.error("Error following/unfollowing user:", error);
}
- }
+ };
return (
@@ -97,7 +106,12 @@ function Profile() {
{!ownAccount && (
-
+
)}
{userData && }
diff --git a/code/frontend/src/types/UserProfile.ts b/code/frontend/src/types/UserProfile.ts
index 2e4e824..ca438de 100644
--- a/code/frontend/src/types/UserProfile.ts
+++ b/code/frontend/src/types/UserProfile.ts
@@ -6,4 +6,5 @@ export type UserProfile = {
followers: number;
following: number;
posts: number;
+ isFollowing: boolean;
}
\ No newline at end of file