Skip to content

Commit

Permalink
뭐징
Browse files Browse the repository at this point in the history
  • Loading branch information
yb3143 committed Jun 15, 2024
2 parents a40cb4d + 50bc795 commit 38cab5e
Show file tree
Hide file tree
Showing 16 changed files with 456 additions and 143 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ yarn-error.log*

# local env files
.env*.local
.env

# vercel
.vercel
Expand Down
28 changes: 14 additions & 14 deletions src/app/(userpage)/types.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,18 @@ export type UserDetail = {

export type UserProduct = {
nextCursor: number;
list: [
{
updatedAt: Date;
createdAt: Date;
writerId: number;
categoryId: number;
favoriteCount: number;
reviewCount: number;
rating: number;
image: string;
name: string;
id: number;
},
];
list: Follow[];
};

export type Follow = {
updatedAt: string;
createdAt: string;
writerId: number;
categoryId: number;
favoriteCount: number;
reviewCount: number;
rating: number;
image: string;
name: string;
id: number;
};
42 changes: 42 additions & 0 deletions src/app/(userpage)/userMock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,45 @@ export const userMock = {
followersCount: 0,
isFollowing: true,
};

export const followMock = {
nextCursor: 0,
list: [
{
updatedAt: "2024-06-03T10:18:50.930Z",
createdAt: "2024-06-03T10:18:50.930Z",
writerId: 0,
categoryId: 1,
favoriteCount: 13,
reviewCount: 14,
rating: 1,
image: `${DEFAULT_PROFILE_IMAGE}`,
name: "닝닝한 빠빠씨",
id: 0,
},
{
updatedAt: "2024-06-03T10:18:50.930Z",
createdAt: "2024-06-03T10:18:50.930Z",
writerId: 0,
categoryId: 1,
favoriteCount: 13,
reviewCount: 14,
rating: 1,
image: `${DEFAULT_PROFILE_IMAGE}`,
name: "닝닝한 빠빠씨",
id: 1,
},
{
updatedAt: "2024-06-03T10:18:50.930Z",
createdAt: "2024-06-03T10:18:50.930Z",
writerId: 0,
categoryId: 1,
favoriteCount: 13,
reviewCount: 14,
rating: 1,
image: `${DEFAULT_PROFILE_IMAGE}`,
name: "닝닝한 빠빠씨",
id: 2,
},
],
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
@import "@/styles/_index";
@import "@/styles/_media";

.container {
display: flex;
flex-direction: column;
gap: 25px;
width: 100%;
height: 100%;
margin-top: 40px;
overflow: auto;

@include respond-to(tablet) {
gap: 20px;
}
}

.listBox {
display: flex;
gap: 20px;
align-items: center;
justify-content: start;

span {
font-size: 18px;

@include font-semibold;

@include respond-to(tablet) {
@include text-normal;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import Link from "next/link";
import React from "react";
import { UserProduct } from "@/app/(userpage)/types";
import { UserImage } from "@/components/UserImage";
import cn from "@/utils/classNames";
import { DEFAULT_PROFILE_IMAGE } from "@/utils/constant";
import styles from "./FollowList.module.scss";

type FollowListProps = {
followData: UserProduct;
};

export default function FollowList({ followData }: FollowListProps) {
console.log(followData);

return (
<div className={cn(styles.container)}>
{followData.list.map((item) => (
<Link
href={`/user/${item.id}`}
key={item.id}
className={cn(styles.listBox)}
>
<UserImage
image={item.image === null ? `${DEFAULT_PROFILE_IMAGE}` : item.image}
nickname={item.name}
size='small'
/>
<span>{item.name}</span>
</Link>
))}
</div>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
@import "@/styles/_index";
@import "@/styles/_media";

.container {
display: flex;
flex-direction: column;
width: 500px;
height: 660px;
padding: 60px 40px 20px;

@include respond-to(tablet) {
height: 600px;
}

@include respond-to(mobile) {
width: 335px;
height: 550px;
padding: 40px 20px 10px;
}
}

.noFollowBox {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
}

.closeButton {
position: absolute;
top: 20px;
right: 20px;
width: 40px;
height: 40px;

@include respond-to(tablet) {
width: 36px;
height: 36px;
}

@include respond-to(mobile) {
top: 15px;
right: 15px;
width: 24px;
height: 24px;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import Image from "next/image";
import { useSession } from "next-auth/react";
import React, { useEffect, useState } from "react";
import { UserProduct } from "@/app/(userpage)/types";
import Modal from "@/components/Modal/Modal";
import cn from "@/utils/classNames";
import { CLOSE_ICON } from "@/utils/constant";
import HttpClient from "@/utils/httpClient";
import styles from "./FollowModal.module.scss";
// eslint-disable-next-line no-restricted-imports
import FollowList from "../FollowList/FollowList";

type ModalProps = {
followState: string;
isModalState: boolean;
setIsModalState: React.Dispatch<React.SetStateAction<boolean>>;
};

export default function FollowModal({ isModalState, setIsModalState, followState }: ModalProps) {
const { data: session } = useSession();
const [followData, setFollowData] = useState<UserProduct>();

const httpClient = new HttpClient(process.env.NEXT_PUBLIC_BASE_URL!);

const handleData = async () => {
if (session && followState) {
const userId = session.user.id;
const ACCESS_TOKEN = session.accessToken;
setFollowData(
await httpClient.get(`users/${userId}/${followState}`, {
headers: { Authorization: ACCESS_TOKEN },
cache: "no-cache",
}),
);
}
};

useEffect(() => {
handleData();
}, [followState]);

const handleClose = () => setIsModalState(false);
return (
<>
{followData !== undefined && isModalState && (
<Modal onClose={handleClose}>
<div className={cn(styles.container)}>
<div
className={cn(styles.closeButton)}
onClick={handleClose}
onKeyDown={handleClose}
role='button'
tabIndex={0}
>
<Image
src={CLOSE_ICON}
alt='닫기버튼'
fill
/>
</div>
<h1>nickname님{followState === "followees" ? "이" : "을"} 팔로우 하는 유저</h1>
{followData.list.length < 1 ? (
<div className={cn(styles.noFollowBox)}>팔로우하는 유저가 없어요</div>
) : (
<FollowList followData={followData} />
)}
</div>
</Modal>
)}
</>
);
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
import React from "react";
/* eslint-disable import/no-named-as-default */
/* eslint-disable jsx-a11y/no-static-element-interactions */
/* eslint-disable jsx-a11y/click-events-have-key-events */
import React, { useState } from "react";
import Button from "@/components/Button/Button";
import { UserImage } from "@/components/UserImage";
import styles from "./UserInfo.module.scss";
// eslint-disable-next-line no-restricted-imports
import FollowModal from "../FollowModal/FollowModal";
// eslint-disable-next-line no-restricted-imports
import HTMLContent from "../HTMLContent/HTMLContent";

type UserInfoProps = {
Expand All @@ -17,45 +22,64 @@ type UserInfoProps = {
export default function UserInfo({ nickname, image, description, follower, folloing, isfollow }: UserInfoProps) {
// textarea에서 쓴 줄바꿈 변환해서 서버로 보내기
// const formattedDescription = description.replace(/\n/g, "<br>")
const [isModalOpen, setIsModalOpen] = useState(false);
const [followModalProps, setFollowModalProps] = useState("");

const handelFolloweesModal = () => {
setFollowModalProps("followees");
setIsModalOpen(true);
};

const handelFollowersModal = () => {
setFollowModalProps("followers");
setIsModalOpen(true);
};

return (
<div className={styles.container}>
<UserImage
image={image}
nickname={nickname}
size='large'
<>
<FollowModal
followState={followModalProps}
isModalState={isModalOpen}
setIsModalState={setIsModalOpen}
/>
<div className={styles.descriptionBox}>
<p>{nickname}</p>
<HTMLContent html={description} />
</div>
<div className={styles.followBox}>
<div>
<p>{follower}</p>
<p>팔로워</p>
<div className={styles.container}>
<UserImage
image={image}
nickname={nickname}
size='large'
/>
<div className={styles.descriptionBox}>
<p>{nickname}</p>
<HTMLContent html={description} />
</div>
<div>
<p>{folloing}</p>
<p>팔로잉</p>
<div className={styles.followBox}>
<div onClick={handelFollowersModal}>
<p>{follower}</p>
<p>팔로워</p>
</div>
<div onClick={handelFolloweesModal}>
<p>{folloing}</p>
<p>팔로잉</p>
</div>
</div>
{isfollow ? (
<Button
styleType='tertiary'
disabled
className='profile'
>
팔로우 취소
</Button>
) : (
<Button
styleType='primary'
disabled={false}
className='profile'
>
팔로우
</Button>
)}
</div>
{isfollow ? (
<Button
styleType='tertiary'
disabled
className='profile'
>
팔로우 취소
</Button>
) : (
<Button
styleType='primary'
disabled={false}
className='profile'
>
팔로우
</Button>
)}
</div>
</>
);
}
Loading

0 comments on commit 38cab5e

Please sign in to comment.