Skip to content

Commit 594bdd0

Browse files
authored
Merge pull request #215 from MBTips/feature/홈페이지-로그인한-경우의-ui-구현
Feature/홈페이지 로그인 했을 때의 기능 구현
2 parents 5d5d33a + 1d3940a commit 594bdd0

File tree

5 files changed

+156
-28
lines changed

5 files changed

+156
-28
lines changed

src/api/axios.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import axios from "axios";
2+
import useAuthStore from "@/store/useAuthStore";
23

34
const instance = axios.create({
45
baseURL: import.meta.env.VITE_API_BASE_URL,
@@ -8,4 +9,33 @@ const instance = axios.create({
89
}
910
});
1011

12+
// 인증 절차가 필요한 API는 authInstance로 HTTP요청
13+
const authInstance = axios.create({
14+
baseURL: import.meta.env.VITE_API_BASE_URL,
15+
timeout: 10000,
16+
headers: {
17+
"Content-Type": "application/json"
18+
}
19+
});
20+
21+
// authInstance 헤더에 accessToken 추가하는 로직
22+
authInstance.interceptors.request.use(
23+
(config) => {
24+
if (!config.headers) {
25+
config.headers = {};
26+
}
27+
28+
const { accessToken } = useAuthStore.getState();
29+
30+
if (accessToken) {
31+
config.headers.Authorization = `Bearer ${accessToken}`;
32+
}
33+
return config;
34+
},
35+
(error) => {
36+
return Promise.reject(error);
37+
}
38+
);
39+
1140
export default instance;
41+
export { authInstance };

src/components/Profile.tsx

Lines changed: 57 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,68 @@
1-
const Profile = () => {
2-
return (
3-
<div className="w-[157px] h-[192px] bg-white rounded-[8px] overflow-hidden relative border border-[#EEEEEE]">
4-
<img
5-
src="/public/icon/dustbin.svg"
6-
alt="Delete"
7-
className="absolute top-3 right-3 w-5 h-5 cursor-pointer"
8-
width={16}
9-
height={16}
10-
/>
1+
import { SetStateAction } from "react";
2+
import { useNavigate } from "react-router-dom";
3+
import { authInstance } from "@/api/axios";
4+
import { VirtualFriend } from "@/types/virtualFreind";
5+
6+
interface ProfileProps {
7+
info: VirtualFriend;
8+
deleteIndex: number;
9+
setVirtualFriendList: React.Dispatch<SetStateAction<VirtualFriend[]>>;
10+
}
11+
const Profile = ({ info, deleteIndex, setVirtualFriendList }: ProfileProps) => {
12+
const navigate = useNavigate();
13+
14+
const handleDelete = async () => {
15+
const res = await authInstance.delete(
16+
`/api/virtual-friend/${info.virtualFriendId}`
17+
);
18+
if (res.status === 200) {
19+
setVirtualFriendList((prevList) =>
20+
prevList.filter((_, index) => index !== deleteIndex)
21+
);
22+
}
23+
};
1124

25+
const handleNavigate = () => {
26+
navigate("/chat", {
27+
state: {
28+
mode: "virtualFriend",
29+
mbti: info.mbti,
30+
id: info.virtualFriendId
31+
}
32+
});
33+
};
34+
35+
return (
36+
<div className="relative h-[192px] w-[157px] overflow-hidden rounded-[8px] border border-[#EEEEEE] bg-white lg:w-[200px]">
37+
<button onClick={handleDelete}>
38+
<img
39+
src="/public/icon/dustbin.svg"
40+
alt="Delete"
41+
className="absolute top-3 right-3 h-5 w-5 cursor-pointer"
42+
width={16}
43+
height={16}
44+
/>
45+
</button>
1246
<img
13-
src="/public/image/ENTP.png"
47+
src={`/public/image/${info.mbti}_profile.png`}
1448
alt="Profile"
15-
className="absolute top-[12px] left-[11px] w-12 h-12 object-cover rounded-full"
49+
className="absolute top-[12px] left-[11px] h-12 w-12 rounded-full object-cover"
1650
/>
1751

18-
<div className="pt-[69px] px-4">
19-
<h2 className="text-base flex items-center space-x-1">
20-
<span className="font-bold">김엠비</span>
21-
<span className="font-light text-gray-600">ENTP</span>
52+
<div className="px-4 pt-[69px]">
53+
<h2 className="flex items-center space-x-1 text-base">
54+
<span className="font-bold">{info.virtualFriendName}</span>
55+
<span className="font-light text-gray-600">{info.mbti}</span>
2256
</h2>
23-
<p className="text-xs text-gray-600 mt-2 font-light">
24-
20대 · 여자 · 직장동료 · 여행 · 사회생활
57+
<p className="mt-2 text-xs font-light text-gray-600">
58+
{info.virtualFriendAge} · {info.virtualFriendSex} ·{" "}
59+
{info.virtualFriendRelationship}
2560
</p>
2661
</div>
27-
28-
<button className="w-full h-[41px] bg-primary-pale text-primary-normal font-bold py-2 text-sm absolute bottom-0">
62+
<button
63+
className="absolute bottom-0 h-[41px] w-full bg-primary-pale py-2 text-sm font-bold text-primary-normal"
64+
onClick={handleNavigate}
65+
>
2966
바로 대화하기
3067
</button>
3168
</div>
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import Profile from "@/components/Profile";
2+
import { VirtualFriend } from "@/types/virtualFreind";
3+
import { SetStateAction } from "react";
4+
5+
interface ProfileContainerProps {
6+
list: VirtualFriend[];
7+
setVirtualFriendList: React.Dispatch<SetStateAction<VirtualFriend[]>>;
8+
}
9+
const ProfileContainer = ({
10+
list,
11+
setVirtualFriendList
12+
}: ProfileContainerProps) => {
13+
return (
14+
<div className="grid grid-cols-2 gap-7">
15+
{list.map((el, index) => (
16+
<Profile
17+
key={index}
18+
info={el}
19+
deleteIndex={index}
20+
setVirtualFriendList={setVirtualFriendList}
21+
/>
22+
))}
23+
</div>
24+
);
25+
};
26+
27+
export default ProfileContainer;

src/components/SubTitle.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ const SubTitle = ({ mode }: { mode: "빠른대화" | "친구목록" }) => {
1515
};
1616

1717
const handleNavigate = () => {
18-
const mode = "virtualFriend";
19-
navigate("/select-info", { state: mode });
18+
const type = mode === "빠른대화" ? "fastFriend" : "virtualFriend";
19+
navigate("/select-info", { state: { type: type } });
2020
};
2121

2222
return (

src/pages/Home.tsx

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,66 @@
1+
import { useEffect, useState } from "react";
2+
import { useNavigate } from "react-router-dom";
3+
import type { AxiosResponse } from "axios";
4+
import { authInstance } from "@/api/axios";
5+
import { VirtualFriend } from "@/types/virtualFreind";
16
import Banner from "@/components/Banner";
27
import StrokeBanner from "@/components/StrokeBanner";
38
import SubTitle from "@/components/SubTitle";
49
import ChatStartButton from "@/components/button/ChatStartButton";
510
import Header from "@/components/header/Header";
11+
import useAuthStore from "@/store/useAuthStore";
12+
import ProfileContainer from "@/components/ProfileContainer";
613

714
const Home = () => {
15+
const navigate = useNavigate();
16+
const { isLoggedIn } = useAuthStore();
17+
const [virtualFreindList, setVirtualFriendList] = useState<VirtualFriend[]>(
18+
[]
19+
);
20+
21+
useEffect(() => {
22+
const fetchFriendList = async () => {
23+
try {
24+
const res: AxiosResponse<{ data: VirtualFriend[] }> =
25+
await authInstance.get("/api/virtual-friend");
26+
setVirtualFriendList(res.data.data);
27+
} catch (err) {
28+
console.error("친구 목록을 불러오지 못했습니다.", err);
29+
navigate("/error");
30+
}
31+
};
32+
33+
if (isLoggedIn) fetchFriendList();
34+
}, [isLoggedIn]);
835

936
return (
10-
<div className="flex flex-col bg-white w-[360px] md:w-[375px] lg:w-[500px]">
11-
<Header/>
37+
<div className="flex w-[360px] flex-col bg-white md:w-[375px] lg:w-[500px]">
38+
<Header />
1239
<main>
1340
<section aria-label="콘텐츠 배너">
1441
<Banner />
1542
</section>
1643
<section className="mt-5 w-full" aria-label="빠른 대화">
17-
<div className="px-[20px] py-[13px] w-full">
44+
<div className="w-full px-[20px] py-[13px]">
1845
<SubTitle mode="빠른대화" />
1946
</div>
2047
<div className="px-5 py-3">
21-
<ChatStartButton mode={"go-fast"}/>
48+
<ChatStartButton mode={"go-fast"} />
2249
</div>
2350
</section>
2451
<section aria-label="친구 목록">
25-
<div className="px-[20px] py-[21px] w-full">
52+
<div className="w-full px-[20px] py-[21px]">
2653
<SubTitle mode="친구목록" />
2754
</div>
2855
<div className="flex justify-center pb-[127px]">
29-
<StrokeBanner />
56+
{isLoggedIn && virtualFreindList.length > 0 ? (
57+
<ProfileContainer
58+
list={virtualFreindList}
59+
setVirtualFriendList={setVirtualFriendList}
60+
/>
61+
) : (
62+
<StrokeBanner />
63+
)}
3064
</div>
3165
</section>
3266
</main>

0 commit comments

Comments
 (0)