Skip to content

Commit ab6c8c8

Browse files
authored
Merge pull request #79 from gyoyeon-kim/card-table
[Fix] Table : 초대받은 대시보드
2 parents 707f380 + f4e76e2 commit ab6c8c8

File tree

7 files changed

+78
-54
lines changed

7 files changed

+78
-54
lines changed

src/api/members.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,6 @@ export const getMembers = async (dashboardId?: string | string[]) => {
2424
},
2525
}
2626
);
27-
console.log(response.data);
28-
console.log(response.data.members);
2927

3028
return response.data.members || [];
3129
};

src/components/modal/ChangeBebridge.tsx

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,29 +2,29 @@ import { useState } from "react";
22
import { useRouter } from "next/router";
33
import Input from "../input/Input";
44
import Image from "next/image";
5-
import axios from "axios";
5+
import axiosInstance from "@/api/axiosInstance";
6+
import { apiRoutes } from "@/api/apiRoutes";
67

7-
export default function ChangeBebridge() {
8+
const ChangeBebridge = () => {
89
const router = useRouter();
9-
const { dashboardId } = router.query;
10+
const { dashboardId } = router.query; // dashboardId 쿼리값 받기
1011
const [title, setTitle] = useState("");
1112
const [selected, setSelected] = useState<number | null>(null);
12-
1313
const colors = ["#7ac555", "#760DDE", "#FF9800", "#76A5EA", "#E876EA"];
14-
1514
const token = process.env.NEXT_PUBLIC_API_TOKEN;
1615

1716
const handleUpdate = async () => {
18-
if (!dashboardId || selected === null || !title) return;
17+
const dashboardIdNumber = Number(dashboardId); // string dashboradId 값 number로 변경
18+
if (!dashboardId || !title || selected === null) return;
1919

2020
const payload = {
2121
title,
2222
color: colors[selected],
2323
};
2424

2525
try {
26-
const response = await axios.put(
27-
`https://sp-taskify-api.vercel.app/13-4/dashboards/${dashboardId}`,
26+
const response = await axiosInstance.put(
27+
apiRoutes.DashboardDetail(dashboardIdNumber),
2828
payload,
2929
{
3030
headers: {
@@ -34,15 +34,16 @@ export default function ChangeBebridge() {
3434
}
3535
);
3636
console.log("업데이트 성공:", response.data);
37-
alert("대시보드가 업데이트되었습니다!");
37+
alert("대시보드가 업데이트되었습니다!"); // 추후에 toast로 변경
38+
window.location.reload();
3839
} catch (error) {
3940
console.error("업데이트 실패:", error);
40-
alert("업데이트에 실패했습니다.");
41+
alert("업데이트에 실패했습니다."); // 추후에 toast로 변경
4142
}
4243
};
4344

4445
return (
45-
<div className="sm:w-[584px] sm:h-[344px] w-[327px] h-[312px] bg-white sm:rounded-[16px] rounded-[8px] shadow-md p-[24px] flex flex-col">
46+
<div className="sm:w-[620px] sm:h-[344px] w-[327px] h-[312px] bg-white sm:rounded-[16px] rounded-[8px] p-[24px] flex flex-col">
4647
<h2 className="text-sm sm:text-[24px] font-bold">비브리지</h2>
4748
<Input
4849
type="text"
@@ -58,29 +59,31 @@ export default function ChangeBebridge() {
5859
<button
5960
className={`cursor-pointer w-[30px] h-[30px] rounded-[15px] mr-2`}
6061
style={{ backgroundColor: color }}
61-
onClick={() => setSelected(index)}
62+
onClick={() => setSelected(index)} // 색상 선택 시 selected 업데이트
6263
/>
6364
{selected === index && (
6465
<Image
6566
src="/svgs/check.svg"
6667
alt="선택됨"
6768
width={23}
6869
height={23}
69-
className=" ursor-pointer absolute top-4 left-3.5 transform -translate-x-1/2 -translate-y-1/2"
70+
className="cursor-pointer absolute top-4 left-3.5 transform -translate-x-1/2 -translate-y-1/2"
7071
/>
7172
)}
7273
</div>
7374
))}
7475
</div>
75-
<div className="mt-8 flex ">
76+
<div className="mt-8 flex">
7677
<button
77-
onClick={handleUpdate}
78-
disabled={!title || selected === null}
79-
className={`cursor-pointer sm:w-[564px] sm:h-[54px] w-[252px] h-[54px] rounded-[8px] border border-[var(--color-gray3)] bg-[var(--primary)] text-[var(--color-white)] ${!title || selected === null ? "bg-gray-300 cursor-not-allowed" : "bg-[var(--primary)]"}`}
78+
onClick={handleUpdate} // 버튼 클릭 시 handleUpdate 함수 호출
79+
disabled={!title || selected === null} // title 또는 color가 없으면 버튼 비활성화
80+
className={`cursor-pointer sm:w-[564px] sm:h-[54px] w-[252px] h-[54px] rounded-[8px] border border-[var(--color-gray3)] bg-[var(--primary)] text-[var(--color-white)] ${!title || selected === null ? "bg-gray-300 cursor-not-allowed" : "bg-[var(--primary)]"}`}
8081
>
8182
변경
8283
</button>
8384
</div>
8485
</div>
8586
);
86-
}
87+
};
88+
89+
export default ChangeBebridge;

src/components/table/InviteRecords.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ const InviteRecords = () => {
3535
};
3636

3737
return (
38-
<div className="relative bg-white p-4 rounded-lg shadow-md max-w-md w-full sm:max-w-lg md:max-w-xl lg:max-w-2xl mx-auto">
38+
<div className="relative bg-white p-4 rounded-lg shadow-md max-w-md w-[620px] lg:h-[474px] sm:max-w-lg md:max-w-xl lg:max-w-2xl mx-auto">
3939
<div className="flex justify-between items-start sm:items-center">
4040
{/* 제목 */}
4141
<p className="sm:text-2xl text-xl font-bold">초대 내역</p>

src/components/table/invited/InvitedDashBoard.tsx

Lines changed: 46 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
import { useState, useEffect, useRef, ChangeEvent } from "react";
22
import Image from "next/image";
3-
import NoDashboardMessage from "./NoResultDashBoard";
3+
import NoResultDashBoard from "./NoResultDashBoard";
44
import EmptyInvitations from "./EmptyInvitations";
55

66
interface Invite {
77
title: string;
88
nickname: string;
99
}
1010

11+
// api데이터로 추후 변경
1112
const invitedData: Invite[] = [
1213
{ title: "프로덕트 디자인", nickname: "손동희" },
1314
{ title: "새로운 기획 문서", nickname: "안귀영" },
@@ -24,9 +25,9 @@ const invitedData: Invite[] = [
2425
const ITEMS_PER_PAGE = 6; // 한 번에 보여줄 개수
2526

2627
function InvitedList({ searchTitle }: { searchTitle: string }) {
27-
const [displayedData, setDisplayedData] = useState<Invite[]>([]); // 보여줄 데이터 상태
28-
const [page, setPage] = useState(1); // 페이지 번호
29-
const observerRef = useRef<HTMLDivElement | null>(null); // IntersectionObserver를 위한 ref
28+
const [displayedData, setDisplayedData] = useState<Invite[]>([]);
29+
const [page, setPage] = useState(1);
30+
const observerRef = useRef<HTMLDivElement | null>(null);
3031

3132
const hasMore = displayedData.length < invitedData.length;
3233

@@ -41,13 +42,10 @@ function InvitedList({ searchTitle }: { searchTitle: string }) {
4142
(entries) => {
4243
entries.forEach((entry) => {
4344
if (entry.isIntersecting) {
44-
console.log("스크롤이 바닥에 도달했습니다.");
4545
if (hasMore) {
4646
console.log("Scroll reached the end. Loading more data...");
4747
setPage((prevPage) => prevPage + 1);
4848
}
49-
} else {
50-
console.log("스크롤이 바닥에서 벗어났습니다.");
5149
}
5250
});
5351
},
@@ -60,15 +58,15 @@ function InvitedList({ searchTitle }: { searchTitle: string }) {
6058

6159
return () => {
6260
if (observerRef.current) {
63-
observer.unobserve(observerRef.current); // cleanup
61+
observer.unobserve(observerRef.current);
6462
}
6563
};
6664
}, [hasMore]);
6765

68-
// 데이터를 로드하는 함수
66+
// 데이터를 로드 함수
6967
const loadMoreData = () => {
70-
const nextData = invitedData.slice(0, page * ITEMS_PER_PAGE); // 페이지에 맞는 데이터만 가져옴
71-
setDisplayedData(nextData); // 데이터를 갱신
68+
const nextData = invitedData.slice(0, page * ITEMS_PER_PAGE);
69+
setDisplayedData(nextData);
7270
};
7371

7472
// 검색 기능
@@ -81,10 +79,10 @@ function InvitedList({ searchTitle }: { searchTitle: string }) {
8179
return (
8280
<div className="relative bg-white w-[260px] sm:w-[504px] lg:w-[1022px] h-[770px] sm:h-[592px] lg:h-[620px] mx-auto mt-[40px]">
8381
{filteredData.length > 0 && (
84-
<div className="p-6 flex w-full h-[26px] justify-start items-center pl-[43px] pr-[76px] md:gap-x-[130px] lg:gap-x-[280px]">
82+
<div className="hidden sm:flex p-6 w-full h-[26px] justify-start items-center pl-[43px] pr-[76px] md:gap-x-[130px] lg:gap-x-[280px]">
8583
<p className="lg:ml-10 font-normal text-[var(--color-gray2)]">이름</p>
8684
<p className="font-normal text-[var(--color-gray2)]">초대자</p>
87-
<p className="lg:ml-6 font-normal text-[var(--color-gray2)]">
85+
<p className="lg:ml-13 font-normal text-[var(--color-gray2)]">
8886
수락여부
8987
</p>
9088
</div>
@@ -94,15 +92,39 @@ function InvitedList({ searchTitle }: { searchTitle: string }) {
9492
? filteredData.map((invite, index) => (
9593
<div
9694
key={index}
97-
className="pb-5 mb-[20px] w-[260px] sm:w-[504px] lg:w-[1022px] h-[50px] sm:grid sm:grid-cols-[1fr_1fr_1fr] sm:items-center flex flex-col gap-2 border-b border-[var(--color-gray4)]"
95+
className="pb-5 mb-[20px] w-[260px] sm:w-[504px] lg:w-[1022px] h-auto sm:h-[50px] sm:grid sm:grid-cols-[1fr_1fr_1fr] sm:items-center flex flex-col gap-10 border-b border-[var(--color-gray4)]"
9896
>
99-
<p className="lg:ml-21 ml-9 flex justify-left mt-1 w-full">
97+
{/* 모바일 레이아웃 */}
98+
<div className="flex flex-col sm:hidden">
99+
<p className="ml-9 mt-1 w-full">
100+
{" "}
101+
<span className="mr-8 text-[var(--color-gray2)]">이름</span>
102+
<span className="text-[#333236]">{invite.title}</span>
103+
</p>
104+
<p className="ml-9 mt-1 w-full">
105+
<span className="mr-3.5 text-[var(--color-gray2)]">
106+
초대자
107+
</span>{" "}
108+
<span className="text-[#333236]">{invite.nickname}</span>
109+
</p>
110+
<div className="flex gap-2 mt-2 justify-center">
111+
<button className="cursor-pointer bg-[var(--primary)] text-white px-3 py-1 rounded-md w-[84px] h-[32px]">
112+
수락
113+
</button>
114+
<button className="cursor-pointer border px-3 py-1 rounded-md w-[84px] h-[32px] text-[var(--primary)] border-[var(--color-gray3)]">
115+
거절
116+
</button>
117+
</div>
118+
</div>
119+
120+
{/* 웹, 태블릿 레이아웃 */}
121+
<p className="lg:ml-21 md:ml-11 ml-9 justify-left mt-1 w-full hidden sm:flex">
100122
{invite.title}
101123
</p>
102-
<p className="lg:ml-12 ml-9 justify-center mt-1">
124+
<p className="lg:mr-25 md:mr-10 ml-9 justify-left mt-1 hidden sm:flex">
103125
{invite.nickname}
104126
</p>
105-
<div className="lg:mr-2 flex gap-2 mt-1 justify-between sm:justify-start">
127+
<div className="lg:mr-5 gap-2 mt-1 mr-2 justify-between sm:justify-start hidden sm:flex">
106128
<button className="cursor-pointer bg-[var(--primary)] text-white px-3 py-1 rounded-md w-[84px] h-[32px]">
107129
수락
108130
</button>
@@ -112,16 +134,15 @@ function InvitedList({ searchTitle }: { searchTitle: string }) {
112134
</div>
113135
</div>
114136
))
115-
: !hasMore && <NoDashboardMessage searchTitle={searchTitle} />}
116-
137+
: !hasMore && <NoResultDashBoard searchTitle={searchTitle} />}{" "}
138+
{/* 검색 내역이 없을 경우*/}
117139
{filteredData.length > 0 && !hasMore && (
118-
<p className="text-center text-gray-400 py-4">
140+
<p className="lg:mr-18 text-center text-gray-400 py-4">
119141
더 이상 초대 목록이 없습니다.
120142
</p>
121143
)}
122-
123144
{hasMore && (
124-
<div ref={observerRef} className="h-[50px] bg-transparent"></div> // 마지막 요소로 스크롤을 감지
145+
<div ref={observerRef} className="h-[50px] bg-transparent"></div> // 마지막 요소로 스크롤 감지
125146
)}
126147
</div>
127148
</div>
@@ -135,19 +156,19 @@ export default function InvitedDashBoard() {
135156
setSearchTitle(event.target.value);
136157
};
137158

138-
// invitedData가 비어 있으면 EmptyInvitations만 렌더링
159+
// invitedData가 비어 있으면 EmptyInvitations만 렌더링 > 초대내역이 아예 없을 경우
139160
if (invitedData.length === 0) {
140161
return <EmptyInvitations />;
141162
}
142163

143164
return (
144165
<div>
145166
<div className="relative bg-white rounded-lg shadow-md w-[260px] sm:w-[504px] lg:w-[1022px] h-[770px] sm:h-[592px] lg:h-[620px] max-w-none mx-auto">
146-
<div className="p-6 relative w-[966px] h-[104px]">
167+
<div className="p-6 relative w-full h-[104px]">
147168
<div className="flex justify-between items-center mb-[32px]">
148169
<p className="text-xl sm:text-2xl font-bold">초대받은 대시보드</p>
149170
</div>
150-
<div className="relative w-[260px] sm:w-[448px] lg:w-[966px]">
171+
<div className="relative w-[228px] sm:w-[448px] lg:w-[966px]">
151172
<input
152173
id="title"
153174
placeholder="검색"

src/components/table/member/MemberList.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ const MemberList: React.FC<HeaderBebridgeProps> = ({ dashboardId }) => {
5252
}, [dashboardId]);
5353

5454
return (
55-
<div className="relative bg-white p-6 rounded-lg shadow-md max-w-md w-full sm:max-w-lg md:max-w-xl lg:max-w-2xl mx-auto">
55+
<div className="lg:h-[404px] relative bg-white p-6 rounded-lg max-w-md w-full lg:w-[620px] sm:max-w-lg md:max-w-xl lg:max-w-2xl mx-auto">
5656
<div className="flex justify-between items-center">
5757
<p className="text-xl sm:text-2xl font-bold">구성원</p>
5858
<Pagination

src/pages/dashboard/[dashboardId]/edit.tsx

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ import { useRouter } from "next/router";
22
import ChangeBebridge from "@/components/modal/ChangeBebridge";
33
import HeaderBebridge from "@/components/Gnb/HeaderBebridge";
44
import MemberList from "@/components/table/member/MemberList";
5+
// import SideMenu from "@/components/SideMenu/SideMenu";
6+
import InviteRecords from "@/components/table/InviteRecords";
57

68
export default function EditDashboard() {
79
const router = useRouter();
@@ -10,11 +12,14 @@ export default function EditDashboard() {
1012
return (
1113
<div>
1214
<HeaderBebridge dashboardId={dashboardId} />
13-
<h1>대시보드 수정 페이지 </h1>
14-
<br />
15-
<h1>dashboardId : {dashboardId}</h1>
15+
<h3>돌아가기</h3>
16+
17+
<div className="flex justify-center items-center">
18+
<ChangeBebridge />
19+
</div>
20+
1621
<MemberList dashboardId={dashboardId} />
17-
<ChangeBebridge />
22+
<InviteRecords />
1823
</div>
1924
);
2025
}

table/button/arrow_forward_ios_FILL0_wght300_GRAD0_opsz24 5.svg

Lines changed: 0 additions & 3 deletions
This file was deleted.

0 commit comments

Comments
 (0)