Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
21 changes: 0 additions & 21 deletions src/app/(home)/_components/RecommendedUsers.css.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,24 +78,3 @@ export const recommendUserNickname = style({
fontWeight: 400,
letterSpacing: '-0.28px',
});

export const followButtonDefault = style({
width: 'auto',
height: 'auto',
padding: '4px 6px',

display: 'flex',
alignItems: 'center',
justifyContent: 'center',

backgroundColor: '#3D95FF',
borderRadius: '20px',
color: vars.color.white,
fontSize: '1.2rem',
fontWeight: '400',
});

export const followButtonFollowing = style({
backgroundColor: vars.color.white,
color: '#8599AD',
});
4 changes: 2 additions & 2 deletions src/app/(home)/_components/RecommendedUsers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { useQuery } from '@tanstack/react-query';
import { QUERY_KEYS } from '@/lib/constants/queryKeys';
import getRecommendedUsers from '@/app/_api/home/getRecommendedUsers';
import { useUser } from '@/store/useUser';
import FollowButton from './FollowButton';
import FollowButton from '@/components/FollowButton/FollowButton';
import { UserProfileType } from '@/lib/types/userProfileType';

import fallbackProfile from '/public/images/fallback_profileImage.webp';
Expand Down Expand Up @@ -128,7 +128,7 @@ function UserRecommendListItem({ data, handleScrollToRight, userId }: UserRecomm
</div>
</Link>
<h6 className={styles.recommendUserNickname}>{data.nickname}</h6>
<FollowButton isFollowing={isFollowing} onClick={handleFollowButtonClick} userId={userId} targetId={data.id} />
<FollowButton isFollowed={isFollowing} onClick={handleFollowButtonClick} userId={data.id} />
</div>
</>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import * as styles from './ListInformation.css';
import * as modalStyles from '@/components/Modal/ModalButton.css';
import LockIcon from '/public/icons/ver3/lock.svg';
import VisibilityIcon from '/public/icons/ver3/visibility.svg';
import FollowButton from '@/app/user/[userId]/_components/FollowButton';
import FollowButton from '@/components/FollowButton/FollowButton';
import getBottomSheetOptionList from '@/app/list/[listId]/_components/ListDetailInner/getBottomSheetOptionList';
import ModalPortal from '@/components/modal-portal';
import BottomSheet from '@/components/BottomSheet/BottomSheet';
Expand All @@ -55,31 +55,32 @@ const convertToCommentType = (data: NewestCommentType): CommentType => ({
isDeleted: false, // 💡 기본값 false 설정
});

// const NewestComment = ({ data }: { data: NewestCommentType }) => {
// return (
// <div>
// <Comment
// comment={convertToCommentType(data)}
// setActiveNickname={() => {}}
// activeNickname={''}
// handleSetCommentId={() => {}}
// handleSetComment={() => {}}
// listId={11}
// commentId={22}
// // currentUserInfo={id: number,nickname: string description?: string profileImageUrl?: string backgroundImageUrl?: string followerCount: number followingCount: number isFollowed: boolean isOwner: boolean}
// handleEdit={() => {}}
// />
// </div>
// );
// };
`
const NewestComment = ({ data }: { data: NewestCommentType }) => {
return (
<div>
<Comment
comment={convertToCommentType(data)}
setActiveNickname={() => {}}
activeNickname={''}
handleSetCommentId={() => {}}
handleSetComment={() => {}}
listId={11}
commentId={22}
// currentUserInfo={id: number,nickname: string description?: string profileImageUrl?: string backgroundImageUrl?: string followerCount: number followingCount: number isFollowed: boolean isOwner: boolean}
handleEdit={() => {}}
/>
</div>
);
};
`;

function ListInformation() {
const { language } = useLanguage();
const params = useParams<{ listId: string }>();
const router = useRouter();
const { onClickMoveToPage } = useMoveToPage();
const { isOn, handleSetOn, handleSetOff } = useBooleanOutput();
const [isFollowed, setIsFollowed] = useState(true);
const [sheetOptionList, setSheetOptionList] = useState<BottomSheetOptionsProps[]>([]);
const [isSheetActive, setSheetActive] = useState<boolean>(false);

Expand All @@ -91,10 +92,10 @@ function ListInformation() {
data: list,
error,
isError,
refetch,
} = useQuery<ListDetailType>({
queryKey: [QUERY_KEYS.getListDetail, params?.listId],
queryFn: () => getListDetail(Number(params?.listId)),
enabled: !!params?.listId,
retry: 0,
});

Expand Down Expand Up @@ -209,7 +210,11 @@ function ListInformation() {
<div className={styles.listOwnerNickname}>{list?.ownerNickname}</div>
</div>
</div>
<div>{userId !== list?.ownerId && <FollowButton userId={list?.ownerId} isFollowed={isFollowed} />}</div>
<div>
{userId && userId !== list?.ownerId && (
<FollowButton isFollowed={list?.isFollowing} userId={list?.ownerId} />
)}
</div>
{/* TODO: 콜라보레이터 기능 주석 */}
{/*<div className={styles.collaboratorWrapper} onClick={handleSetOn}>*/}
{/* <Collaborators collaborators={filteredCollaborators} />*/}
Expand Down
5 changes: 2 additions & 3 deletions src/app/user/locale.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,15 @@ export const userLocale = {
follower: '아직은 팔로워가 없어요',
following: '아직 팔로우한 사람이 없어요',
},
follow: '팔로우',
follower: '팔로워',
following: '팔로잉',
cancelFollow: '팔로우 취소',
total: '총',
people: '명',
myList: '마이 리스트',
collaboList: '콜라보 리스트',
noListMessage: '해당 카테고리에 아직 리스트가 없어요',
cancelFollow: '팔로우 취소',
follow: '팔로우',

confirm: '확인',
goToMypage: '마이페이지로 이동하기',
profileImageAlt: '프로필 이미지',
Expand Down
24 changes: 24 additions & 0 deletions src/components/FollowButton/FollowButton.css.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { style } from '@vanilla-extract/css';
import { vars } from '@/styles/theme.css';

export const followButtonDefault = style({
width: 'auto',
height: 'auto',
padding: '4px 6px',

display: 'flex',
alignItems: 'center',
justifyContent: 'center',

backgroundColor: vars.color.blue,
borderRadius: '20px',
color: vars.color.white,
fontSize: '1.2rem',
fontWeight: '400',
});

export const followButtonFollowing = style({
backgroundColor: vars.color.white,
color: vars.color.bluegray8,
border: `0.5px solid ${vars.color.bluegray8}`,
});
Original file line number Diff line number Diff line change
Expand Up @@ -9,52 +9,44 @@ import getUserOne from '@/app/_api/user/getUserOne';

import { QUERY_KEYS } from '@/lib/constants/queryKeys';
import { UserType } from '@/lib/types/userProfileType';
import { useUser } from '@/store/useUser';
import toasting from '@/lib/utils/toasting';
import toastMessage, { MAX_FOLLOWING } from '@/lib/constants/toastMessage';
import * as styles from './RecommendedUsers.css';

import useBooleanOutput from '@/hooks/useBooleanOutput';
import Modal from '@/components/Modal/Modal';
import LoginModal from '@/components/login/LoginModal';
import { useLanguage } from '@/store/useLanguage';
import { commonLocale } from '@/components/locale';

import * as styles from './FollowButton.css';

interface FollowButtonProps {
isFollowing: boolean;
onClick: () => void;
isFollowed: boolean;
onClick?: () => void;
userId: number;
targetId: number;
}

function FollowButton({ isFollowing, onClick, userId, targetId }: FollowButtonProps) {
const { language } = useLanguage();
function FollowButton({ isFollowed, onClick, userId }: FollowButtonProps) {
const queryClient = useQueryClient();
const { language } = useLanguage();
const { user: userMe } = useUser();
const { isOn, handleSetOff, handleSetOn } = useBooleanOutput();

const { data: userMeData } = useQuery<UserType>({
queryKey: [QUERY_KEYS.userOne, userId],
queryFn: () => getUserOne(userId),
enabled: !!userId,
retry: 1,
queryKey: [QUERY_KEYS.userOne, userMe.id],
queryFn: () => getUserOne(userMe.id as number),
enabled: !!userMe.id,
});

const followUserMutation = useMutation({
mutationKey: [isFollowing ? QUERY_KEYS.deleteFollow : QUERY_KEYS.follow, targetId],
mutationFn: isFollowing ? () => deleteFollowUser(targetId) : () => createFollowUser(targetId),
mutationKey: [isFollowed ? QUERY_KEYS.deleteFollow : QUERY_KEYS.follow, userId],
mutationFn: isFollowed ? () => deleteFollowUser(userId) : () => createFollowUser(userId),
onMutate: async () => {
await queryClient.cancelQueries({ queryKey: [QUERY_KEYS.userOne, userId] });
const previousFollower: UserType | undefined = queryClient.getQueryData([QUERY_KEYS.userOne, userId]);

if (!previousFollower) return;

const nextData = {
...previousFollower,
isFollowed: !isFollowing,
followerCount: isFollowing ? previousFollower.followerCount - 1 : previousFollower.followerCount + 1,
};

queryClient.setQueryData([QUERY_KEYS.userOne, userId], nextData);

return { previousFollower };
},
onError: (error: AxiosError, userId: number, context) => {
Expand All @@ -67,27 +59,31 @@ function FollowButton({ isFollowing, onClick, userId, targetId }: FollowButtonPr
queryClient.invalidateQueries({
queryKey: [QUERY_KEYS.userOne, userId],
});
queryClient.invalidateQueries({
queryKey: [QUERY_KEYS.getListDetail],
});
},
});

const handleFollowUser = (isFollowing: boolean) => () => {
if (!isFollowing) {
const handleFollowUser = (isFollowed: boolean) => () => {
if (!isFollowed) {
if (userMeData && userMeData?.followingCount >= MAX_FOLLOWING) {
toasting({ type: 'warning', txt: toastMessage[language].limitFollow });
return;
}
}
followUserMutation.mutate(userId);
onClick();
if (onClick) onClick();
};

return (
<>
<button
className={`${styles.followButtonDefault} ${isFollowing === true ? styles.followButtonFollowing : ''}`}
onClick={handleFollowUser(isFollowing)}
className={`${styles.followButtonDefault} ${isFollowed === true && styles.followButtonFollowing}`}
onClick={handleFollowUser(isFollowed)}
disabled={followUserMutation.isPending}
>
<span>{isFollowing ? commonLocale[language].following : commonLocale[language].follow}</span>
<span>{isFollowed ? commonLocale[language].following : commonLocale[language].follow}</span>
</button>
{isOn && (
<Modal handleModalClose={handleSetOff} size="large">
Expand Down
1 change: 1 addition & 0 deletions src/lib/types/listType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ export interface ListDetailType {
items: ItemType[];
isCollected: boolean;
isPublic: boolean;
isFollowing: boolean;
backgroundPalette: BACKGROUND_COLOR_PALETTE_TYPE;
backgroundColor: string;
collectCount: number;
Expand Down