Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
228a0f8
[feat] initial setting up for Tanstack-query
seongjin2427 Oct 18, 2024
a834e53
[style] added fill props "gray" of ProfileEditButton Component
seongjin2427 Oct 24, 2024
4d66fb0
Merge branch 'develop' of https://github.com/f-lab-edu/Prostargram-fr…
seongjin2427 Nov 5, 2024
78e8bf6
[feat] added useTimer hook
seongjin2427 Nov 7, 2024
1d15de0
Merge branch 'develop' of https://github.com/f-lab-edu/Prostargram-fr…
seongjin2427 Nov 7, 2024
127bf8a
[feat] added FieldTimerButton in Field Component
seongjin2427 Nov 7, 2024
06d6904
[feat] update for email confirmation retry in Field Component and use…
seongjin2427 Nov 7, 2024
7a31bea
[feat] update Field Component Naming
seongjin2427 Nov 20, 2024
22d4cd3
[feat] complete first sign up step page
seongjin2427 Nov 21, 2024
34756ab
[feat] added logic of request server api for additional Info page
seongjin2427 Nov 23, 2024
054a84e
[feat] modify error message for username duplicate
seongjin2427 Nov 23, 2024
f97a7e0
[refact] refactored sign up page (included github sign up)
seongjin2427 Nov 24, 2024
dbfeabc
[feat] add login login after being successful sign up step
seongjin2427 Nov 29, 2024
f7d2b2e
[feat] added login login after being successfule sign up step at Gith…
seongjin2427 Nov 29, 2024
8258783
[refact] reduce unneccessary code of useAdditionalInfoForm hook logic
seongjin2427 Nov 29, 2024
2a5fa64
[feat] merge from develop branch
seongjin2427 Dec 11, 2024
f2ccc82
Merge branch 'develop' of https://github.com/f-lab-edu/Prostargram-fr…
seongjin2427 Jan 9, 2025
1277ca8
[feat] complete sign-up additional page
seongjin2427 Jan 9, 2025
3562b2d
[feat] connect social-account and my-information server api
seongjin2427 Jan 13, 2025
2c5e835
[feat] connect interest server api
seongjin2427 Jan 13, 2025
bc999aa
[feat] connect follower/following server api
seongjin2427 Jan 14, 2025
c3aef62
[feat] connect update profile image server api
seongjin2427 Jan 14, 2025
17c4f7e
[feat] update getProfile server api with useQuery
seongjin2427 Jan 14, 2025
07ecb17
[feat] update follower/following logic and ui
seongjin2427 Jan 14, 2025
7632ade
[feat] update toggle active of Profile image modify logic
seongjin2427 Jan 14, 2025
304aeef
[feat] force to always lowercase when user adds interest
seongjin2427 Jan 14, 2025
09e8683
[feat] temporary redirect when user try to move incorrect search para…
seongjin2427 Jan 14, 2025
4d5674f
[feat] update ProfileFollowButton
seongjin2427 Jan 16, 2025
1a984d6
[feat] add server request logic only for getting follower list
seongjin2427 Jan 21, 2025
1a1b88f
Merge branch 'develop' of https://github.com/f-lab-edu/Prostargram-fr…
seongjin2427 Jan 22, 2025
c66b18e
[feat] add request server api of profile feeds and change name my.ts …
seongjin2427 Jan 22, 2025
11c1d1d
[refact] combine request api for getting follower and following
seongjin2427 Jan 22, 2025
673cd24
[feat] prevent copy and paste at input in LoginPage (/auth)
seongjin2427 Jan 30, 2025
a881d83
[feat] prevent moving to go to home when logo is clicked
seongjin2427 Jan 30, 2025
b54742c
[feat] indicate required message after clicking submit with empty inp…
seongjin2427 Jan 30, 2025
26846af
[feat] update regexp for password
seongjin2427 Jan 30, 2025
dc261a9
[feat] remove auto-complete style and add logic to execute with enter…
seongjin2427 Jan 30, 2025
81d09c7
[feat] after sending email, reset button is rendered with timer concu…
seongjin2427 Jan 30, 2025
afb26b9
[fix] change invalid input message when user submitted inexistent id …
seongjin2427 Feb 4, 2025
78befd3
[refact] refactoring signup page
seongjin2427 Feb 4, 2025
3f8bec6
[style] move AuthLayout position to center direction
seongjin2427 Feb 5, 2025
0e4f989
[refact] remove unnecessary hook and reduce useSocialAccountServerReq…
seongjin2427 Feb 5, 2025
9139bd7
[refact] change socialAccount with react-hook-form fieldArray API to …
seongjin2427 Feb 5, 2025
bdf7122
[refact] remove react-hook-form API
seongjin2427 Feb 5, 2025
763ce82
[refact] combine with addUserInterest and addRecommendedInterest
seongjin2427 Feb 5, 2025
bb130f3
[feat] remove react-hook-form Array API logic
seongjin2427 Feb 10, 2025
73f5ac7
[feat] split hooks with useUserInterests and useUserSocialAccount
seongjin2427 Feb 10, 2025
37512e8
[refact] remove unnecessary empty object
seongjin2427 Feb 10, 2025
19db30d
Merge branch 'develop' of https://github.com/f-lab-edu/Prostargram-fr…
seongjin2427 Feb 10, 2025
7d6dd4e
[feat] update profile page logic
seongjin2427 Feb 10, 2025
2b3c3a6
[feat] add Suspense at MainLayout Component to resolve deploy error i…
seongjin2427 Feb 10, 2025
bc08a48
Merge branch 'feature/auth-feedback' into feature/connect-my-page-api
seongjin2427 Feb 10, 2025
1092a0a
[feat] add profile image upload logic
seongjin2427 Feb 11, 2025
4c7f680
[feat] add get profile feeds logic and MyFeeds Component
seongjin2427 Feb 13, 2025
b745793
[refact] refactoring Profile Component
seongjin2427 Feb 13, 2025
d4aa7ba
[feat] update logic of MyInformation Component
seongjin2427 Feb 17, 2025
c2e5a2c
[refact] refactoring some Components of MyPage
seongjin2427 Feb 17, 2025
92b2024
Merge branch 'develop' of https://github.com/f-lab-edu/Prostargram-fr…
seongjin2427 Feb 18, 2025
5c08eb1
[feat] add paragraph for none of social account at other user profile…
seongjin2427 Feb 18, 2025
b77e074
[feat] add paragraph for empty of interests at profile page
seongjin2427 Feb 18, 2025
0a13be7
[feat] add social account icons, update add/remove logic of social ac…
seongjin2427 Feb 19, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion public/mock/user.json

This file was deleted.

13 changes: 9 additions & 4 deletions src/api/follow/apis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,17 @@ interface FollowingRes {
userName: string;
}

const getFollowingList = (userId: number) => {
export type GetFollowListParamType = {
userId: number;
type: 'followings' | 'followers';
};

const getFollowList = ({ userId, type }: GetFollowListParamType) => {
const res = authInstance<FollowingRes[]>({
method: 'get',
url: `/users/${userId}/followings`,
url: `/users/${userId}/${type}`,
});
return res;
};

export { followUser, unfollowUser, getFollowingList };
export { followUser, unfollowUser, getFollowList };
export type { FollowingRes };
13 changes: 8 additions & 5 deletions src/api/follow/followQueries.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import { useQuery } from '@tanstack/react-query';
import { getFollowingList } from './apis';
import { GetFollowListParamType, getFollowList } from './apis';

export const FOLLOWINGS_QUERY_KEYS = {
followings: ['followings'] as const,
FOLLOW: (keys: (string | number)[]) => ['follow', ...keys],
};

export const useGetFollowingList = (userId: number, options = {}) => {
export const useGetFollowList = (
{ userId, type }: GetFollowListParamType,
options = {},
) => {
return useQuery({
queryKey: FOLLOWINGS_QUERY_KEYS.followings,
queryFn: () => getFollowingList(userId),
queryKey: FOLLOWINGS_QUERY_KEYS.FOLLOW([userId, type]),
queryFn: () => getFollowList({ userId, type }),
...options,
});
};
9 changes: 4 additions & 5 deletions src/api/info.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
import { authInstance } from './httpRequest';

const postSocialAccount = async (socialAccount: string) => {
const postSocialAccount = async (socialAccountUrl: string) => {
const url = `/social-accounts`;

const result = await authInstance({
method: 'POST',
url,
data: socialAccount,
data: { socialAccountUrl },
});

return result;
};

const removeSocialAccount = async (socialAccount: string) => {
const removeSocialAccount = async (socialAccountUrl: string) => {
const url = `/social-accounts`;

const result = await authInstance({
method: 'DELETE',
url,
data: socialAccount,
data: { socialAccountUrl },
});

return result;
Expand Down Expand Up @@ -50,7 +50,6 @@ const removeInterest = async ({
hashTagId: number;
name: string;
}) => {
console.log(name);
const url = `/users/${userId}/interests?hashTagId=${hashTagId}&name=${encodeURIComponent(name)}`;

const result = await authInstance({
Expand Down
3 changes: 2 additions & 1 deletion src/api/profile.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { UserType } from '@/app/profile/types/my';
import { getUserId } from '@/utils/manageToken';
import { UserType } from '@/app/profile/types/profile';

import { authInstance, defaultInstance } from './httpRequest';

export const updateMyLinks = async (myLinks: (File | string)[]) => {
Expand Down
137 changes: 137 additions & 0 deletions src/api/profile/apis.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
import { getUserId } from '@/utils/manageToken';
import { UserType } from '@/app/profile/types/profile';
import { authInstance } from '../httpRequest';

export const getProfile = async (userId: number) => {
const result = await authInstance<UserType>({
method: 'GET',
url: `/users/${userId}/profile_page`,
});

return result;
};

export const getProfileFeeds = async ({
userId,
pageParam,
}: {
userId: number;
pageParam?: number;
}) => {
const result = await authInstance<Feed.FeedsResponse>({
method: 'GET',
url: `/users/${userId}/profile-feeds`,
params: {
lastPostId: pageParam,
},
});

return {
data: result.result?.data ?? [],
hasNextPage:
result.result?.hasNextPage && result.result?.data.at(-1)?.post.postId,
};
};

export const updateProfileInfo = async (data: {
username: string;
departmentName: string;
selfIntroduction: string;
}) => {
const userId = getUserId();

const result = await authInstance({
method: 'PATCH',
url: `/users/${userId}/profile-info`,
data,
});

return result;
};

type UploadImageUrlType = {
contentUrls: string[];
preSignedUrls: string[];
};

const requestProfileImageUrls = async (imageCount: number) => {
const result = await authInstance<UploadImageUrlType>({
method: 'POST',
url: `/images`,
data: { imageCount, fileType: 'PROFILE_IMAGE' },
});

return result;
};

const uploadImageWithPresignedUrl = async ({
contentUrls,
preSignedUrls,
imgFiles,
}: {
contentUrls: string[];
preSignedUrls: string[];
imgFiles: File[];
}) => {
const response = await Promise.all(
preSignedUrls.map((url, index) =>
fetch(url, {
method: 'PUT',
headers: {
'Content-Type': imgFiles[index].type,
},
body: imgFiles[index],
}),
),
);

if (response.some((res) => !res?.ok)) {
throw new Error('이미지 업로드에 실패 했습니다. 다시 시도해주세요.');
}

return response.map((_, index) => ({
contentUrl: contentUrls[index],
}));
};

const uploadContentUrl = async (
userId: number,
urls: { contentUrl: string }[],
) => {
return Promise.all(
urls.map((imgUrl) =>
authInstance({
method: 'PATCH',
url: `/users/${userId}/profile-image`,
data: imgUrl,
}),
),
);
};

export const updateProfileImage = async ({
imgFiles,
}: {
imgFiles: File[];
}) => {
const userId = getUserId();

const { isSuccess, result: urls } = await requestProfileImageUrls(
imgFiles.length,
);

if (isSuccess && urls) {
const { contentUrls, preSignedUrls } = urls;
const imageContentUrls = await uploadImageWithPresignedUrl({
contentUrls,
preSignedUrls,
imgFiles,
});

const response = await uploadContentUrl(userId, imageContentUrls);

return response;
}

return [];
};
42 changes: 42 additions & 0 deletions src/api/profile/profileMutation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { UseMutationOptions, useMutation } from '@tanstack/react-query';

import { updateProfileImage, updateProfileInfo } from './apis';
import {
HttpResponseType,
HttpSuccessType,
ResponseError,
} from '../httpRequest';

const useProfileInfoMutation = (
options?: UseMutationOptions<
HttpSuccessType<unknown>,
ResponseError,
{
username: string;
departmentName: string;
selfIntroduction: string;
}
>,
) => {
return useMutation({
mutationFn: updateProfileInfo,
...options,
});
};

const useProfileImageMutation = (
options?: UseMutationOptions<
(HttpResponseType & {
result?: unknown;
})[],
ResponseError,
{ imgFiles: File[] }
>,
) => {
return useMutation({
mutationFn: updateProfileImage,
...options,
});
};

export { useProfileInfoMutation, useProfileImageMutation };
63 changes: 63 additions & 0 deletions src/api/profile/profileQuery.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import {
UseInfiniteQueryOptions,
UseQueryOptions,
useInfiniteQuery,
useQuery,
} from '@tanstack/react-query';

import { UserType } from '@/app/profile/types/profile';
import { getProfileFeeds, getProfile } from './apis';
import { HttpSuccessType, ResponseError } from '../httpRequest';

export const PROPFILE_QUERY_KEYS = {
DEFAULT: 'default_profile',
PROFILE: (keys: number[]) => [
'my_profile',
PROPFILE_QUERY_KEYS.DEFAULT,
...keys,
],
FEEDS: (keys: (string | number)[]) => [
'feeds',
PROPFILE_QUERY_KEYS.DEFAULT,
...keys,
],
};

const useGetProfileInformation = (
userId: number,
options?: UseQueryOptions<HttpSuccessType<UserType>, ResponseError>,
) => {
return useQuery({
queryKey: PROPFILE_QUERY_KEYS.PROFILE([userId]),
queryFn: () => getProfile(userId),
...options,
});
};

type ProfileFeedType = {
data: Feed.FeedData[];
hasNextPage: number | false | undefined;
};

const useGetProfileFeeds = (
userId: number,
options?: UseInfiniteQueryOptions<
ProfileFeedType,
ResponseError,
Feed.FeedData[],
ProfileFeedType,
ReturnType<typeof PROPFILE_QUERY_KEYS.FEEDS>,
number | undefined
>,
) => {
return useInfiniteQuery({
queryKey: PROPFILE_QUERY_KEYS.FEEDS([userId]),
queryFn: async ({ pageParam }) => getProfileFeeds({ userId, pageParam }),
select: (data) => data.pages[0].data,
getNextPageParam: (lastPage) => lastPage.hasNextPage || undefined,
initialPageParam: undefined,
...options,
});
};

export { useGetProfileInformation, useGetProfileFeeds };
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,16 @@
import { useRouter } from 'next/navigation';
import Image from 'next/image';
import Typo from '@/components/common/Typo';
import { useGetFollowingList } from '@/api/follow/followQueries';

import { getUserId } from '@/utils/manageToken';
import { useGetFollowList } from '@/api/follow/followQueries';

import styles from './FollowingList.module.scss';

const FollowingList = () => {
const userId = getUserId();

const { data: followings } = useGetFollowingList(userId);
const { data: followings } = useGetFollowList({ type: 'followings', userId });
const router = useRouter();

const moveUserProfilePage = (followingUserId: number) => {
Expand All @@ -24,6 +25,7 @@ const FollowingList = () => {
followings?.result?.map((user) => {
return (
<li
key={user.userId}
className={styles.following_li}
onClick={() => moveUserProfilePage(user.userId!)}
aria-hidden="true"
Expand Down
12 changes: 12 additions & 0 deletions src/app/profile/[slug]/page.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
@use '../../../styles/helpers/index' as *;

.container {
@include res--desktop {
width: 66.875rem;
border: 1px solid $COLOR_GRAY_3;
border-radius: 10px;
background-color: $COLOR_WHITE;
margin: 1.875rem auto 10rem auto;
overflow: hidden;
}
}
Loading
Loading