Skip to content

Commit be4a800

Browse files
authored
Merge pull request #120 from hhjin1/card-hj
[Style] Card: 반응형 / Dashboard Page: 반응형
2 parents cd54558 + a2c44f0 commit be4a800

File tree

8 files changed

+125
-55
lines changed

8 files changed

+125
-55
lines changed

package-lock.json

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
"react-dom": "^19.0.0",
2424
"react-hook-form": "^7.54.2",
2525
"react-toastify": "^11.0.5",
26+
"tostify": "^0.0.1",
2627
"zustand": "^5.0.3"
2728
},
2829
"devDependencies": {

src/components/button/ColumnsButton.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ const ColumnsButton: React.FC<ButtonProps> = ({
1717
className={clsx(
1818
"flex justify-center items-center gap-[10px] bg-white transition-all",
1919
"rounded-lg px-4 py-3 font-semibold",
20-
"border border-gray-300 hover:border-purple-500",
20+
"border border-gray-200 hover:border-purple-500",
2121
fullWidth ? "w-full" : "w-[284px] md:w-[544px] lg:w-[354px]", // 반응형 너비
2222
"h-[70px] md:h-[70px] lg:h-[70px]", // 반응형 높이
2323
"mt-[10px] md:mt-[16px] lg:mt-[20px]", // 여백

src/components/button/TodoButton.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ const TodoButton: React.FC<ButtonProps> = ({
1717
className={clsx(
1818
"flex justify-center items-center gap-[10px] bg-white transition-all",
1919
"rounded-lg px-4 py-3 font-semibold",
20-
"border border-gray-300 hover:border-purple-500",
20+
"border border-gray-200 hover:border-purple-500",
2121
fullWidth ? "w-full" : "w-[284px] md:w-[544px] lg:w-[314px]", // 반응형 너비
2222
"h-[32px] md:h-[40px] lg:h-[40px]", // 반응형 높이
2323
"mt-[10px] md:mt-[16px] lg:mt-[20px]", // 여백

src/components/columnCard/Card.tsx

Lines changed: 80 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -14,46 +14,90 @@ export default function Card({
1414
imageUrl,
1515
}: CardProps) {
1616
return (
17-
<div className="w-[314px] border border-[0.25px] border-gray-200 rounded-md p-4">
17+
<div
18+
className={`
19+
flex flex-col md:flex-row lg:flex-col
20+
items-start rounded-md bg-white border border-gray-200 p-4
21+
w-[284px] sm:w-full md:w-[544px] md:h-[93px] lg:w-[314px] lg:h-auto
22+
`}
23+
>
24+
{/* 이미지 영역 */}
1825
{imageUrl && (
19-
<Image
20-
className="w-full h-40 object-cover rounded-md"
21-
src={imageUrl}
22-
width={300}
23-
height={160}
24-
alt="Task Image"
25-
/>
26-
)}
27-
<h3 className="text-lg ">{title}</h3>
28-
<div className="flex items-center gap-2 mt-2">
29-
{tags.map((tag, idx) => (
30-
<span
31-
key={idx}
32-
className={`px-2 py-1 rounded-md text-sm ${
33-
idx % 3 === 0
34-
? "bg-[#F9EEE3] text-[#D58D49]"
35-
: idx % 3 === 1
36-
? "bg-[#F7DBF0] text-[#D549B6]"
37-
: "bg-[#DBE6F7] text-[#4981D5]"
38-
}`}
39-
>
40-
{tag}
41-
</span>
42-
))}
43-
</div>
44-
<div className="flex items-center justify-between mt-2">
45-
<div className="flex items-center gap-2.5 text-gray-500 text-sm">
26+
<div
27+
className={`
28+
mb-2 md:mb-0 md:mr-4 lg:mr-0
29+
shrink-0
30+
w-full h-40
31+
md:w-[91px] md:h-[53px]
32+
lg:w-full lg:h-40
33+
`}
34+
>
4635
<Image
47-
src="/svgs/calendar.svg"
48-
alt="calendar icon"
49-
width={16}
50-
height={16}
51-
priority
36+
className="rounded-md object-cover w-full h-full"
37+
src={imageUrl}
38+
alt="Task Image"
39+
width={300}
40+
height={160}
5241
/>
53-
<p>{dueDate}</p>
5442
</div>
55-
<div className="w-7 h-7 flex items-center justify-center bg-[#A3C4A2] text-white font-bold rounded-full text-sm">
56-
{assignee.nickname[0]}
43+
)}
44+
45+
{/* 텍스트 콘텐츠 영역 */}
46+
<div className="flex flex-col justify-between flex-1 w-full">
47+
{/* 제목 */}
48+
<h3
49+
className={`
50+
text-lg font-semibold mt-2
51+
md:text-sm md:mt-0
52+
lg:text-lg lg:mt-2
53+
truncate
54+
`}
55+
>
56+
{title}
57+
</h3>
58+
59+
{/* 태그 + 날짜 + 닉네임 */}
60+
<div
61+
className={`
62+
flex flex-col gap-2 mt-2
63+
md:flex-row md:items-center md:justify-between md:mt-1
64+
lg:flex-col lg:items-start lg:mt-2
65+
text-sm md:text-xs
66+
`}
67+
>
68+
{/* 태그들 */}
69+
<div className="flex gap-1 flex-wrap">
70+
{tags.map((tag, idx) => (
71+
<span
72+
key={idx}
73+
className={`px-2 py-0.5 rounded-md text-xs font-medium ${
74+
idx % 3 === 0
75+
? "bg-[#F9EEE3] text-[#D58D49]"
76+
: idx % 3 === 1
77+
? "bg-[#F7DBF0] text-[#D549B6]"
78+
: "bg-[#DBE6F7] text-[#4981D5]"
79+
}`}
80+
>
81+
{tag}
82+
</span>
83+
))}
84+
</div>
85+
86+
{/* 날짜 + 닉네임 */}
87+
<div className="flex items-center gap-2 md:gap-3 text-gray-500">
88+
<div className="flex items-center gap-1">
89+
<Image
90+
src="/svgs/calendar.svg"
91+
alt="calendar"
92+
width={16}
93+
height={16}
94+
/>
95+
<span>{dueDate}</span>
96+
</div>
97+
<div className="w-6 h-6 flex items-center justify-center bg-[#A3C4A2] text-white font-bold rounded-full text-xs">
98+
{assignee.nickname[0]}
99+
</div>
100+
</div>
57101
</div>
58102
</div>
59103
</div>

src/components/columnCard/Column.tsx

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
1+
// Column.tsx
12
import { useEffect, useState } from "react";
23
import Image from "next/image";
34
import { CardType } from "@/types/task";
45
import Card from "./Card";
56
import TodoModal from "@/components/modalInput/ToDoModal";
67
import TodoButton from "@/components/button/TodoButton";
7-
import ColumnManageModal from "@/components/columncard/ColumnManageModal";
8-
import ColumnDeleteModal from "@/components/columncard/ColumnDeleteModal";
8+
import ColumnManageModal from "@/components/columnCard/ColumnManageModal";
9+
import ColumnDeleteModal from "@/components/columnCard/ColumnDeleteModal";
910
import { updateColumn, deleteColumn } from "@/api/dashboards";
1011
import { getDashboardMembers } from "@/api/card";
12+
import { MemberType } from "@/types/users";
1113

1214
type ColumnProps = {
1315
columnId: number;
@@ -41,7 +43,7 @@ export default function Column({
4143
dashboardId,
4244
});
4345

44-
const parsed = result.map((m: any) => ({
46+
const parsed = result.map((m: MemberType) => ({
4547
id: m.id,
4648
userId: m.userId,
4749
nickname: m.nickname || m.email,
@@ -85,7 +87,13 @@ export default function Column({
8587
};
8688

8789
return (
88-
<div className="w-[354px] flex flex-col rounded-md border-r border-gray-200 bg-gray-50 p-4 min-h-screen">
90+
<div
91+
className={`
92+
flex flex-col border-r border-gray-200 bg-gray-50 rounded-md p-4
93+
h-auto sm:m-h-screen
94+
max-h-[401px] sm:max-h-none
95+
`}
96+
>
8997
{/* 칼럼 헤더 */}
9098
<div className="flex items-center justify-between">
9199
<div className="flex items-center gap-2">
@@ -108,19 +116,27 @@ export default function Column({
108116
</div>
109117

110118
{/* 카드 영역 */}
111-
<div className="flex-1 pb-4 flex flex-col items-center gap-3">
112-
<div onClick={() => setIsTodoModalOpen(true)}>
119+
<div className=" flex-1 pb-4 flex flex-col items-center gap-3 ">
120+
<div onClick={() => setIsTodoModalOpen(true)} className="mb-2">
113121
<TodoButton />
114122
</div>
115123

116-
{tasks.map((task) => (
117-
<Card
118-
key={task.id}
119-
{...task}
120-
imageUrl={task.imageUrl}
121-
assignee={task.assignee}
122-
/>
123-
))}
124+
{/* 카드 1개만 렌더링 (모바일), 전체 렌더링 (md 이상) */}
125+
<div className="w-full flex flex-wrap justify-center gap-3">
126+
{tasks.map((task, index) => {
127+
const isMobile =
128+
typeof window !== "undefined" && window.innerWidth < 768;
129+
if (isMobile && index > 0) return null;
130+
return (
131+
<Card
132+
key={task.id}
133+
{...task}
134+
imageUrl={task.imageUrl}
135+
assignee={task.assignee}
136+
/>
137+
);
138+
})}
139+
</div>
124140
</div>
125141

126142
{/* Todo 모달 */}

src/components/modal/NewDashboard.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ export default function NewDashboard({
3535
try {
3636
setLoading(true);
3737
const response = await axios.post(
38-
`${process.env.NEXT_PUBLIC_BASE_URL}13-4/dashboards`,
38+
`${process.env.NEXT_PUBLIC_BASE_URL}/13-4/dashboards`,
3939
payload,
4040
{
4141
headers: {

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// src/pages/dashboard/[dashboardId]/index.tsx
12
import React, { useState, useEffect } from "react";
23
import { useRouter } from "next/router";
34
import {
@@ -107,7 +108,7 @@ export default function Dashboard() {
107108
<div className="flex flex-col flex-1 overflow-hidden">
108109
<HeaderDashboard variant="dashboard" dashboardId={dashboardId} />
109110

110-
<div className="flex overflow-x-auto ">
111+
<div className="flex-1 overflow-x-auto flex flex-col md:flex-col lg:flex-row ">
111112
{/* 각 칼럼 렌더링 */}
112113
{columns.map((col) => (
113114
<Column
@@ -119,8 +120,9 @@ export default function Dashboard() {
119120
dashboardId={Number(dashboardId)}
120121
/>
121122
))}
122-
<div className="p-5">
123+
<div className="p-12">
123124
<ColumnsButton onClick={openModal} />
125+
{/* todo 모바일, 테블릿 위치에서 뷰포트 아래로 가도록 */}
124126
</div>
125127
{/* 칼럼 추가 모달 */}
126128
{isAddColumnModalOpen && (

0 commit comments

Comments
 (0)