Skip to content

Commit 73da143

Browse files
authored
Merge pull request #61 from prgrms-fe-devcourse/feat/UserList
[Feat/userList] 유저 리스트 모달창 토글 기능 및 유저 리스트 기능 추가
2 parents 270b8ed + f3f74b4 commit 73da143

File tree

4 files changed

+76
-18
lines changed

4 files changed

+76
-18
lines changed

src/components/UserList.tsx

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,27 @@
11
import { ChevronDown } from "lucide-react";
22
import UserListCard from "./UserListCard";
3-
import { useState } from "react";
3+
import { useEffect, useState } from "react";
4+
import { useUserStore } from "../stores/userListStore";
5+
import { useLocation } from "react-router";
46

57
export default function UserList() {
68
const [isOpen, setIsOpen] = useState(false);
9+
const location = useLocation();
10+
const { userList, fetchUsers } = useUserStore();
11+
12+
// 페이지 이동 시 자동으로 닫기
13+
useEffect(() => {
14+
setIsOpen(false);
15+
}, [location.pathname]);
16+
17+
useEffect(() => {
18+
fetchUsers();
19+
}, [fetchUsers]);
20+
721
/* 필요한 정보 */
822
/* 프로필 이미지, 이름, 소속, 학년(전공 과목), auth_id */
923
return (
10-
<div className="absolute left-10 bottom-0 w-80 bg-white rounded-t-xl flex flex-col">
24+
<div className="absolute left-10 bottom-0 w-90 bg-white rounded-t-xl flex flex-col">
1125
{/* 헤더 */}
1226
<div
1327
className="cursor-pointer flex flex-row justify-between items-center px-5 py-3 w-full bg-violet-500 rounded-t-xl"
@@ -25,21 +39,14 @@ export default function UserList() {
2539

2640
{/* 슬라이딩 리스트 */}
2741
<div
28-
className={`pt-2 overflow-hidden transition-all duration-500 ease-in-out ${
29-
isOpen ? "max-h-160" : "max-h-0"
42+
className={` transition-all duration-500 ease-in-out pb-4 ${
43+
isOpen ? "h-160 overflow-y-auto" : "h-0 overflow-y-hidden"
3044
}`}
3145
>
3246
<div className="flex flex-col">
33-
<UserListCard />
34-
<UserListCard />
35-
<UserListCard />
36-
<UserListCard />
37-
<UserListCard />
38-
<UserListCard />
39-
<UserListCard />
40-
<UserListCard />
41-
<UserListCard />
42-
<UserListCard />
47+
{userList.map((user) => (
48+
<UserListCard key={user.auth_id} user={user} />
49+
))}
4350
</div>
4451
</div>
4552
</div>

src/components/UserListCard.tsx

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,20 @@
11
import { Link } from "react-router";
2+
import { getAge } from "../utils/getAge";
3+
import { getGrade } from "../utils/getGrade";
4+
5+
export default function UserListCard({ user }: { user: User }) {
6+
const age = user.birth_date ? getAge(user.birth_date) : 0;
7+
const grade = user.role === "student" && getGrade(age);
8+
9+
const roleMap: Record<string, string> = {
10+
student: "학생",
11+
teacher: "선생님",
12+
parent: "학부모",
13+
};
214

3-
export default function UserListCard() {
415
return (
516
<>
6-
<Link to={`/profile/해당 프로필 유저 Id`}>
17+
<Link to={`/profile/${user.auth_id}`}>
718
<div className="flex flex-row justify-between items-center py-4 px-5 hover:bg-[#F1F3F5]">
819
{/* left */}
920
<div className="flex flex-row items-center gap-2.5">
@@ -17,9 +28,13 @@ export default function UserListCard() {
1728
{/* 정보 */}
1829
<div className="flex flex-col gap-1 text-sm">
1930
{/* 이름 */}
20-
<div>홍길동</div>
31+
<div className="line-clamp-1">{user.nickname}</div>
2132
{/* 소속, 학년 (선생님은 전공) */}
22-
<div>학생, 3학년</div>
33+
<div>
34+
{roleMap[user.role] || "알 수 없음"}
35+
{user.role === "student" && `, ${grade}`}{" "}
36+
{user.role === "teacher" && `, ${user.major}`}
37+
</div>
2338
</div>
2439
</div>
2540
{/* right */}

src/stores/userListStore.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { create } from "zustand";
2+
import { immer } from "zustand/middleware/immer";
3+
import supabase from "../utils/supabase";
4+
5+
type UserListState = {
6+
userList: User[];
7+
// fetchUsers: 전체 유저 리스트 가져오기
8+
fetchUsers: () => Promise<void>;
9+
};
10+
11+
export const useUserStore = create<UserListState>()(
12+
immer((set) => ({
13+
userList: [],
14+
// 전체 유저 리스트 가져오기
15+
fetchUsers: async () => {
16+
try {
17+
const { data, error } = await supabase
18+
.from("users")
19+
.select("*");
20+
if (error) throw error;
21+
22+
set({ userList: data || [] });
23+
} catch (err) {
24+
console.error("유저 목록 로딩 오류:", err);
25+
}
26+
},
27+
})),
28+
);

src/types/user.d.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
type User = {
2+
auth_id: string;
3+
nickname: string;
4+
online?: string;
5+
role: string;
6+
birth_date?: Date;
7+
major?: string;
8+
};

0 commit comments

Comments
 (0)