Skip to content

Commit 5c8dc92

Browse files
authored
fix: 회고 분석 팀 스페이스 분석 탭 진입 시 에러 (depromeet#699)
* chore: 일부 스타일링 개선 * chore: 분석 데이터 null 처리 추가 * refactor: depromeet#658 반복되는 형태 리팩토링 * feat: 인사이트 아이콘 이름 타입 정의 및 사용 통일
1 parent 34edf6c commit 5c8dc92

7 files changed

Lines changed: 153 additions & 131 deletions

File tree

apps/web/src/app/desktop/component/analysis/AnalysisDialog/AnalysisTab.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ export default function AnalysisTab({ analysisData }: AnalysisTabProps) {
4343
return <LoadingModal />;
4444
}
4545

46-
if (hasAIAnalyzed == true) {
46+
if (hasAIAnalyzed === false) {
4747
return <Analyzing />;
4848
}
4949

apps/web/src/app/desktop/component/analysis/AnalysisDialog/Analyzing.tsx

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,16 @@ import { Icon } from "@/component/common/Icon";
22
import { Spacing } from "@/component/common/Spacing";
33
import { Typography } from "@/component/common/typography";
44
import { DESIGN_TOKEN_COLOR } from "@/style/designTokens";
5-
import { css } from "@emotion/react";
5+
import { css, keyframes } from "@emotion/react";
6+
7+
const bounce = keyframes`
8+
0%, 100% {
9+
transform: translateY(0);
10+
}
11+
50% {
12+
transform: translateY(-10px);
13+
}
14+
`;
615

716
export default function Analyzing() {
817
return (
@@ -15,7 +24,14 @@ export default function Analyzing() {
1524
align-items: center;
1625
`}
1726
>
18-
<Icon icon="ic_new_clock" size={7.2} color={DESIGN_TOKEN_COLOR.gray500} />
27+
<div
28+
css={css`
29+
display: inline-block;
30+
animation: ${bounce} 1.5s ease-in-out infinite;
31+
`}
32+
>
33+
<Icon icon="ic_new_clock" size={7.2} color={DESIGN_TOKEN_COLOR.gray500} />
34+
</div>
1935
<Spacing size={2} />
2036
<Typography
2137
variant="title18Bold"

apps/web/src/app/desktop/component/analysis/AnalysisDialog/RetrospectsOverview.tsx

Lines changed: 125 additions & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,129 @@
11
import { Icon } from "@/component/common/Icon";
22
import { Typography } from "@/component/common/typography";
33
import { DESIGN_TOKEN_COLOR } from "@/style/designTokens";
4-
import { Insight } from "@/types/analysis";
4+
import { Insight, InsightIconName } from "@/types/analysis";
55
import { css } from "@emotion/react";
66

77
type RetrospectsOverviewProps = {
88
description: string;
9-
goodPoints: Insight[];
10-
badPoints: Insight[];
11-
improvementPoints: Insight[];
9+
goodPoints: Insight[] | null;
10+
badPoints: Insight[] | null;
11+
improvementPoints: Insight[] | null;
1212
};
1313

14+
type InsightSectionProps = {
15+
title: string;
16+
data: Insight[] | null;
17+
emptyMessage: string;
18+
iconName: InsightIconName;
19+
};
20+
21+
type InsightItemProps = {
22+
content: string;
23+
iconName: InsightIconName;
24+
};
25+
26+
/**
27+
* 잘 하고 있는 점, 부족한 점, 개선이 필요한 점이 없는 경우 표시되는 컴포넌트
28+
*
29+
* @param message 빈 상태 메시지
30+
* @returns
31+
*/
32+
const EmptyState = ({ message }: { message: string }) => (
33+
<div
34+
css={css`
35+
display: flex;
36+
align-items: center;
37+
justify-content: center;
38+
height: 100%;
39+
padding: 2rem;
40+
`}
41+
>
42+
<Typography variant="body14Medium" color="gray500">
43+
{message}
44+
</Typography>
45+
</div>
46+
);
47+
48+
/**
49+
* 인사이트 아이템 컴포넌트
50+
* 잘 하고 있는 점 / 부족한 점 / 개선이 필요한 점 리스트에서 사용
51+
*
52+
* @param content 아이템 내용
53+
* @param iconName 아이콘 이름
54+
* @returns
55+
*/
56+
const InsightItem = ({ content, iconName }: InsightItemProps) => (
57+
<div
58+
css={css`
59+
display: flex;
60+
align-items: center;
61+
gap: 1.2rem;
62+
height: 4.4rem;
63+
padding: 1.2rem 1.6rem;
64+
background-color: white;
65+
border-radius: 0.8rem;
66+
`}
67+
>
68+
<Icon icon={iconName} size={1.6} />
69+
<Typography variant="subtitle14Bold" color="gray800">
70+
{content}
71+
</Typography>
72+
</div>
73+
);
74+
75+
/**
76+
* 인사이트(잘 하고 있는 점, 부족한 점, 개선이 필요한 점) 섹션 컴포넌트
77+
*
78+
* @param title 섹션 제목
79+
* @param data 섹션 데이터
80+
* @param emptyMessage 데이터가 없을 때 표시할 메시지
81+
* @param iconName 아이콘 이름
82+
* @returns
83+
*/
84+
const InsightSection = ({ title, data, emptyMessage, iconName }: InsightSectionProps) => {
85+
const isEmpty = data === null || data.length === 0;
86+
87+
return (
88+
<div
89+
css={css`
90+
display: flex;
91+
flex-direction: column;
92+
gap: 2rem;
93+
flex: 1;
94+
`}
95+
>
96+
<Typography variant="title16Bold" color="gray900">
97+
{title}
98+
</Typography>
99+
{isEmpty ? (
100+
<EmptyState message={emptyMessage} />
101+
) : (
102+
<div
103+
css={css`
104+
display: flex;
105+
flex-direction: column;
106+
gap: 0.8rem;
107+
`}
108+
>
109+
{data.map((item, index) => (
110+
<InsightItem key={index} content={item.content} iconName={iconName} />
111+
))}
112+
</div>
113+
)}
114+
</div>
115+
);
116+
};
117+
118+
/**
119+
* 회고 개요 컴포넌트
120+
*
121+
* @param description 회고 설명
122+
* @param goodPoints 잘 하고 있는 점
123+
* @param badPoints 부족한 점
124+
* @param improvementPoints 개선이 필요한 점
125+
* @returns
126+
*/
14127
export default function RetrospectsOverview({ description, goodPoints, badPoints, improvementPoints }: RetrospectsOverviewProps) {
15128
return (
16129
<article>
@@ -57,7 +170,6 @@ export default function RetrospectsOverview({ description, goodPoints, badPoints
57170
padding: 2.4rem 2rem;
58171
`}
59172
>
60-
{/* ---------- 회고 내용 3개 컬럼 ---------- */}
61173
<div
62174
css={css`
63175
display: flex;
@@ -66,128 +178,16 @@ export default function RetrospectsOverview({ description, goodPoints, badPoints
66178
height: 100%;
67179
`}
68180
>
69-
{/* ---------- 잘 하고 있어요 ---------- */}
70-
<div
71-
css={css`
72-
display: flex;
73-
flex-direction: column;
74-
gap: 2rem;
75-
flex: 1;
76-
`}
77-
>
78-
<Typography variant="title16Bold" color="gray900">
79-
잘 하고 있어요
80-
</Typography>
81-
<div
82-
css={css`
83-
display: flex;
84-
flex-direction: column;
85-
gap: 0.8rem;
86-
`}
87-
>
88-
{goodPoints.map((item, index) => (
89-
<div
90-
key={index}
91-
css={css`
92-
display: flex;
93-
align-items: center;
94-
gap: 1.2rem;
95-
height: 4.4rem;
96-
padding: 1.2rem 1.6rem;
97-
background-color: white;
98-
border-radius: 0.8rem;
99-
`}
100-
>
101-
<Icon icon="ic_good_mark" size={1.6} />
102-
<Typography variant="subtitle14Bold" color="gray800">
103-
{item.content}
104-
</Typography>
105-
</div>
106-
))}
107-
</div>
108-
</div>
181+
<InsightSection title="잘 하고 있어요" data={goodPoints} emptyMessage="잘하고 있는 점이 없어요." iconName="ic_good_mark" />
109182

110-
{/* ---------- 이런 점은 부족해요 ---------- */}
111-
<div
112-
css={css`
113-
display: flex;
114-
flex-direction: column;
115-
gap: 2rem;
116-
flex: 1;
117-
`}
118-
>
119-
<Typography variant="title16Bold" color="gray900">
120-
이런 점은 부족해요
121-
</Typography>
122-
<div
123-
css={css`
124-
display: flex;
125-
flex-direction: column;
126-
gap: 0.8rem;
127-
`}
128-
>
129-
{badPoints.map((item, index) => (
130-
<div
131-
key={index}
132-
css={css`
133-
display: flex;
134-
align-items: center;
135-
gap: 1.2rem;
136-
height: 4.4rem;
137-
padding: 1.2rem 1.6rem;
138-
background-color: white;
139-
border-radius: 0.8rem;
140-
`}
141-
>
142-
<Icon icon="ic_bad_mark_red" size={1.6} />
143-
<Typography variant="subtitle14Bold" color="gray800">
144-
{item.content}
145-
</Typography>
146-
</div>
147-
))}
148-
</div>
149-
</div>
183+
<InsightSection title="이런 점은 부족해요" data={badPoints} emptyMessage="부족한 점이 없어요." iconName="ic_bad_mark_red" />
150184

151-
{/* ---------- 개선이 필요해요 ---------- */}
152-
<div
153-
css={css`
154-
display: flex;
155-
flex-direction: column;
156-
gap: 2rem;
157-
flex: 1;
158-
`}
159-
>
160-
<Typography variant="title16Bold" color="gray900">
161-
개선이 필요해요
162-
</Typography>
163-
<div
164-
css={css`
165-
display: flex;
166-
flex-direction: column;
167-
gap: 0.8rem;
168-
`}
169-
>
170-
{improvementPoints.map((item, index) => (
171-
<div
172-
key={index}
173-
css={css`
174-
display: flex;
175-
align-items: center;
176-
gap: 1.2rem;
177-
height: 4.4rem;
178-
padding: 1.2rem 1.6rem;
179-
background-color: white;
180-
border-radius: 0.8rem;
181-
`}
182-
>
183-
<Icon icon="ic_improve_blue_mark" size={1.6} />
184-
<Typography variant="subtitle14Bold" color="gray800">
185-
{item.content}
186-
</Typography>
187-
</div>
188-
))}
189-
</div>
190-
</div>
185+
<InsightSection
186+
title="개선이 필요해요"
187+
data={improvementPoints}
188+
emptyMessage="개선이 필요한 점이 없어요."
189+
iconName="ic_improve_blue_mark"
190+
/>
191191
</div>
192192
</section>
193193
</article>

apps/web/src/component/retrospect/space/CompletedRetrospects.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ export default function CompletedRetrospects() {
4949
border: 1px dashed rgba(0, 0, 0, 0.12);
5050
border-radius: 1.2rem;
5151
margin-top: 1.6rem;
52+
margin-bottom: 1.6rem;
5253
flex: 1;
5354
`}
5455
>

apps/web/src/component/retrospect/space/InProgressRetrospects.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ export default function InProgressRetrospects() {
9696
border: 1px dashed rgba(0, 0, 0, 0.12);
9797
border-radius: 1.2rem;
9898
margin-top: 1.6rem;
99+
margin-bottom: 1.6rem;
99100
flex: 1;
100101
`}
101102
>

apps/web/src/types/analysis/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ export type analysisType = "goodPoints" | "badPoints" | "improvementPoints";
22

33
export type analysisItemType = "GOOD" | "BAD" | "IMPROVEMENT";
44

5+
export type InsightIconName = "ic_good_mark" | "ic_bad_mark_red" | "ic_improve_blue_mark";
6+
57
export type Insight = {
68
isTeam: boolean;
79
analyzeType: analysisItemType;

apps/web/src/utils/analysis/getAnalysisConfig.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,25 @@
1+
import { InsightIconName } from "@/types/analysis";
2+
13
type AnalysisType = "good" | "bad" | "improvement";
24

35
// * 타입에 따른 통합 객체 설정
46
const ANALYSIS_CONFIG = {
57
good: {
68
emoji: "👍",
79
title: "잘 하고 있어요",
8-
icon: "ic_good_mark" as const,
10+
icon: "ic_good_mark" as InsightIconName,
911
pointKey: "goodPoint" as const,
1012
},
1113
bad: {
1214
emoji: "😢",
1315
title: "이런 점은 부족해요",
14-
icon: "ic_bad_mark_red" as const,
16+
icon: "ic_bad_mark_red" as InsightIconName,
1517
pointKey: "badPoint" as const,
1618
},
1719
improvement: {
1820
emoji: "🙌",
1921
title: "개선이 필요해요",
20-
icon: "ic_improve_mark" as const,
22+
icon: "ic_improve_mark" as InsightIconName,
2123
pointKey: "improvementPoint" as const,
2224
},
2325
} as const;

0 commit comments

Comments
 (0)