Skip to content
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/api/myProjectList.api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import type {
import { httpClient } from './http.api';

export const getMyProjectLists = async () => {
const response = await httpClient.get<ApiManagedProjects>(`/project/my`);
const response = await httpClient.get<ApiManagedProjects>(`/user/project`);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

API 엔드포인트 변경을 확인했습니다.

엔드포인트가 /project/my에서 /user/project로 변경되었습니다. 백엔드 API 구조 변경에 따른 것으로 보입니다.

다른 파일에서 기존 엔드포인트를 사용하는 곳이 있는지 확인해보겠습니다:


🏁 Script executed:

#!/bin/bash
# Description: 기존 /project/my 엔드포인트를 사용하는 다른 파일 확인
# Expected: 모든 곳에서 일관되게 업데이트되었는지 확인

rg "/project/my" --type ts --type tsx

Length of output: 65


기존 /project/my 엔드포인트 사용처를 다시 한 번 전체 파일(.ts, .tsx)에서 확인합니다:


🏁 Script executed:

#!/bin/bash
# Description: /project/my 엔드포인트가 사용된 모든 .ts 및 .tsx 파일 검색
rg "/project/my" --glob '*.ts' --glob '*.tsx'

Length of output: 128


/project/my 엔드포인트 교체 및 디버깅 로그 제거 필요

다음 두 군데를 수정해주세요:

  • src/api/myProjectList.api.ts
    • 디버깅용 console.log(response) 제거
  • src/mock/manageProjectList.ts
    • 기존 ${import.meta.env.VITE_API_BASE_URL}/project/my${import.meta.env.VITE_API_BASE_URL}/user/project로 엔드포인트 변경
🤖 Prompt for AI Agents
In src/api/myProjectList.api.ts at line 8, remove the debugging console.log
statement that outputs the response after calling the updated endpoint
`/user/project`. Also, ensure that in src/mock/manageProjectList.ts the API
endpoint string is updated from
`${import.meta.env.VITE_API_BASE_URL}/project/my` to
`${import.meta.env.VITE_API_BASE_URL}/user/project` to reflect the backend API
change.

console.log(response);
return response.data;
};

Expand Down
4 changes: 3 additions & 1 deletion src/api/mypage.api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,9 @@ export const patchMyProfileImg = async (file: File) => {

export const getMyJoinedProjectList = async () => {
try {
const response = await httpClient.get<ApiJoinedProject>('/user/project');
const response = await httpClient.get<ApiJoinedProject>(
'/user/joinProject'
);

return response.data;
} catch (error) {
Expand Down
3 changes: 3 additions & 0 deletions src/assets/line.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
41 changes: 41 additions & 0 deletions src/components/admin/mainCard/MainCard.styled.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { Link } from 'react-router-dom';
import styled from 'styled-components';

export const Container = styled.div`
display: flex;
flex-direction: column;
border: 1px solid #ccc;
border-radius: ${({ theme }) => theme.borderRadius.primary};
`;

export const CardHeader = styled.div`
min-height: 50px;
display: flex;
justify-content: space-between;
align-items: center;
`;

export const Title = styled.h3`
margin-left: 20px;
`;

export const ShowAllArea = styled(Link)`
display: flex;
margin-left: 10px;
margin-right: 10px;
`;

export const ShowAllButton = styled.button`
font-size: 13px;
margin-right: 6px;
`;

export const ArrowRight = styled.img`
font-size: 13px;
`;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

ArrowRight 스타일 개선: img에 font-size 속성 비적용
<img> 요소에 font-size는 적용되지 않습니다. width/height를 사용하거나 SVG 컴포넌트를 활용해 아이콘 크기를 조절하고, 대체 텍스트(alt="")를 명시해 접근성을 확보하세요.

export const ArrowRight = styled.img`
-  font-size: 13px;
+  width: 13px;
+  height: auto;
`;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export const ArrowRight = styled.img`
font-size: 13px;
`;
export const ArrowRight = styled.img`
width: 13px;
height: auto;
`;
🤖 Prompt for AI Agents
In src/components/admin/mainCard/MainCard.styled.ts around lines 33 to 35, the
ArrowRight styled component applies font-size to an img element, which has no
effect. Replace font-size with appropriate width and height properties to
control the image size. Additionally, ensure that when using this component, an
alt attribute with meaningful or empty text is provided for accessibility.
Consider using an SVG component for better scalability and styling control.


export const Line = styled.hr``;

export const Wrapper = styled.div``;

export const MainContent = styled.div``;
31 changes: 31 additions & 0 deletions src/components/admin/mainCard/MainCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import * as S from './MainCard.styled';
import arrowRight from '../../../assets/ArrowRight.svg';
import React from 'react';

interface MainCardProps {
title: string;
moreLink?: string;
children: React.ReactNode;
}

const MainCard = ({ title, moreLink, children }: MainCardProps) => {
return (
<S.Container>
<S.CardHeader>
<S.Title>{title}</S.Title>
{moreLink && (
<S.ShowAllArea to={moreLink}>
<S.ShowAllButton>전체 보기</S.ShowAllButton>
<S.ArrowRight src={arrowRight} />
</S.ShowAllArea>
)}
</S.CardHeader>
<S.Line />
<S.Wrapper>
<S.MainContent>{children}</S.MainContent>
</S.Wrapper>
</S.Container>
);
};

export default MainCard;
3 changes: 3 additions & 0 deletions src/components/admin/mainCard/graphCard/GraphCard.styled.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import styled from 'styled-components';

export const Container = styled.div``;
8 changes: 8 additions & 0 deletions src/components/admin/mainCard/graphCard/GraphCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import React from 'react';
import * as S from './GraphCard.styled';

const GraphCard = () => {
return <S.Container>GraphCard Component</S.Container>;
};

export default GraphCard;
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import styled from 'styled-components';

export const Container = styled.div``;
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import React from 'react';
import * as S from './AllUserPreview.styled';

const AllUserPreview = () => {
return <S.Container>AllUserPreview Component</S.Container>;
};

export default AllUserPreview;
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import styled from 'styled-components';

export const Container = styled.div``;
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import React from 'react';
import * as S from './InquiresPreview.styled';

const InquiresPreview = () => {
return <S.Container>InquiresPreview Component</S.Container>;
};

export default InquiresPreview;
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import styled from 'styled-components';

export const Container = styled.div`
display: flex;
flex-direction: column;
padding: 20px;
`;

export const Wrapper = styled.div`
display: flex;
`;

export const Dot = styled.img`
margin-right: 7px;
`;

export const NoticeTitle = styled.p`
font-size: 18px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import React from 'react';
import * as S from './NoticePreview.styled';
import { useGetNotice } from '../../../../hooks/user/useGetNotice';
import line from '../../../../assets/line.svg';

const NoticePreview = () => {
const { noticeData } = useGetNotice({ keyword: '', page: 1 });

return (
<S.Container>
{noticeData?.notices.map((notice) => (
<S.Wrapper>
<S.Dot src={line} />
<S.NoticeTitle>{notice.title}</S.NoticeTitle>
</S.Wrapper>
))}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

React key prop 누락 및 안전한 렌더링 개선이 필요합니다.

정적 분석 도구에서 지적한 대로 map 함수에서 key prop이 누락되었고, 안전한 렌더링을 위한 개선이 필요합니다.

다음 수정사항을 적용해주세요:

-      {noticeData?.notices.map((notice) => (
-        <S.Wrapper>
+      {noticeData?.notices?.map((notice) => (
+        <S.Wrapper key={notice.id || notice.title}>
           <S.Dot src={line} />
           <S.NoticeTitle>{notice.title}</S.NoticeTitle>
         </S.Wrapper>
       ))}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
{noticeData?.notices.map((notice) => (
<S.Wrapper>
<S.Dot src={line} />
<S.NoticeTitle>{notice.title}</S.NoticeTitle>
</S.Wrapper>
))}
{noticeData?.notices?.map((notice) => (
<S.Wrapper key={notice.id || notice.title}>
<S.Dot src={line} />
<S.NoticeTitle>{notice.title}</S.NoticeTitle>
</S.Wrapper>
))}
🧰 Tools
🪛 Biome (1.9.4)

[error] 12-12: Missing key property for this element in iterable.

The order of the items may change, and having a key can help React identify which item was moved.
Check the React documentation.

(lint/correctness/useJsxKeyInIterable)

🤖 Prompt for AI Agents
In src/components/admin/previewComponent/noticePreview/NoticePreview.tsx around
lines 11 to 16, the map function rendering the notices is missing a unique key
prop on the root element inside the loop, which is required for React to
efficiently track list items. Add a unique key prop to the <S.Wrapper> element,
preferably using a unique identifier from each notice such as notice.id or a
stable unique value. Also, ensure safe rendering by verifying that noticeData
and noticeData.notices exist before mapping to avoid runtime errors.

</S.Container>
);
};

export default NoticePreview;
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import styled from 'styled-components';

export const Container = styled.div``;
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import React from 'react';
import * as S from './ReportsPreview.styled';

const ReportsPreview = () => {
return <S.Container>ReportsPreview Component</S.Container>;
};

export default ReportsPreview;
40 changes: 20 additions & 20 deletions src/components/common/header/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,13 @@ import loadingImg from '../../../assets/loadingImg.svg';
import { useModal } from '../../../hooks/useModal';
import Modal from '../modal/Modal';
import { formatImgPath } from '../../../util/formatImgPath';
// import bell from '../../../assets/bell.svg';
// import Notification from './Notification/Notification';
// import bellLogined from '../../../assets/bellLogined.svg';
// import { useEffect } from 'react';
// import { testLiveAlarm } from '../../../api/alarm.api';
import bell from '../../../assets/bell.svg';
import Notification from './Notification/Notification';
import bellLogined from '../../../assets/bellLogined.svg';
import { useMyProfileInfo } from '../../../hooks/user/useMyInfo';
import { useNotificationContext } from '../../../context/SseContext';
import { useEffect } from 'react';
import { testLiveAlarm } from '../../../api/alarm.api';
import { ROUTES } from '../../../constants/routes';

function Header() {
Expand All @@ -26,24 +27,26 @@ function Header() {
const isLoggedIn = useAuthStore((state) => state.isLoggedIn);
const { myData, isLoading } = useMyProfileInfo();

const { signalData, clearSignal } = useNotificationContext();

const handleClickLogout = () => {
userLogout();
useAuthStore.persist.clearStorage();
localStorage.clear();
};

// const { signalData, setSignalData } = useNotification();

// useEffect(() => {
// testLiveAlarm();
// }, []);

const profileImg = myData?.profileImg
? `${import.meta.env.VITE_APP_IMAGE_CDN_URL}/${formatImgPath(
myData.profileImg
)}?w=86&h=86&fit=crop&crop=entropy&auto=format,enhance&q=60`
: DefaultImg;

useEffect(() => {
if (process.env.NODE_ENV === 'deployment') {
testLiveAlarm();
}
}, []);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

환경 조건 확인 필요

NODE_ENV'deployment'인 경우에만 테스트 알림을 호출하고 있는데, 이 환경 값이 정확한지 확인이 필요합니다.

일반적으로 Node.js 환경에서는 'production', 'development', 'test' 값을 사용합니다. 'deployment'가 의도된 값인지 확인해보세요:

만약 'production'이 맞다면 수정이 필요합니다.


🏁 Script executed:

#!/bin/bash
# 프로젝트에서 사용하는 NODE_ENV 값들 확인
echo "=== package.json의 scripts 확인 ==="
cat package.json | jq '.scripts'

echo "=== 빌드/배포 설정 파일들에서 NODE_ENV 사용 확인 ==="
rg "NODE_ENV" --type json --type js --type ts -A 2 -B 2

Length of output: 1096


환경 변수 NODE_ENV 값 검토 및 수정 필요

현재 src/components/common/header/Header.tsx 44–48라인에서 아래와 같이 NODE_ENV === 'deployment' 일 때만 testLiveAlarm()을 호출하고 있습니다.
하지만 코드베이스 전반에 'deployment' 환경은 사용되지 않으며, 일반적으로 Node.js/React 프로젝트에서는 'production'을 사용합니다.

  • 파일: src/components/common/header/Header.tsx
    위치: 44–48라인
    수정 전:
    useEffect(() => {
      if (process.env.NODE_ENV === 'deployment') {
        testLiveAlarm();
      }
    }, []);
    제안:
    • 의도한 환경 값이 정말 'deployment'인지 확인
    • 표준 환경값인 'production'으로 변경이 필요하다면 아래와 같이 수정
      useEffect(() => {
        if (process.env.NODE_ENV === 'production') {
          testLiveAlarm();
        }
      }, []);
🤖 Prompt for AI Agents
In src/components/common/header/Header.tsx at lines 44 to 48, the code checks if
process.env.NODE_ENV equals 'deployment' before calling testLiveAlarm(), but
'deployment' is not a standard NODE_ENV value. Verify if 'deployment' is the
intended environment; if not, replace the string 'deployment' with 'production'
to align with common Node.js/React environment naming conventions.


return (
<S.HeaderContainer>
<Link to={ROUTES.main}>
Expand All @@ -58,26 +61,23 @@ function Header() {
<S.HeaderLink>공지사항</S.HeaderLink>
</Link>
</S.HeaderLinkContainer>
{/* <S.Alarm role='button' tabIndex={0} aria-label='알림 메세지'>
<S.Alarm role='button' tabIndex={0} aria-label='알림 메세지'>
{isLoggedIn ? (
<DropDown
toggleButton={
signalData ? (
<S.BellButton onClick={() => setSignalData(null)}>
<img src={bellLogined} alt='알림' />
{signalData && <S.Dot />}
</S.BellButton>
) : (
<S.BellButton onClick={clearSignal}>
<img src={bellLogined} alt='알림' />
)
{signalData && <S.Dot />}
</S.BellButton>
}
comment={false}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

DropDown 컴포넌트에 comment prop 추가

comment={false} prop이 추가되었는데, 이 prop의 목적과 기본값이 명확하지 않습니다.

DropDown 컴포넌트의 comment prop 용도를 확인해보세요:

이 prop이 필수인지, 기본값은 무엇인지 확인하여 일관성을 맞춰주세요.

Also applies to: 92-92


🏁 Script executed:

#!/bin/bash
# DropDown 컴포넌트에서 comment prop 사용 확인
echo "=== DropDown 컴포넌트의 comment prop 정의 확인 ==="
ast-grep --pattern 'interface $_ {
  $$$
  comment$_: $_
  $$$
}'

echo "=== comment prop 사용 예시 확인 ==="
rg "comment.*=" src/components/common/dropDown/ -A 3 -B 3

Length of output: 1286


DropDown 컴포넌트에 comment prop 정의 및 기본값 지정 필요

DropDown.tsx에서 comment={false}를 통해 styled panel에 $comment을 전달하고 있으나,
DropDownProps 인터페이스에 해당 prop 정의가 없고 기본값도 설정되어 있지 않습니다.
아래 사항을 반영해주세요:

  • src/components/common/dropDown/DropDown.tsx
    • DropDownProps 인터페이스에 comment?: boolean 항목 추가
    • 컴포넌트 인수 혹은 defaultProps를 이용해 comment 기본값을 false로 지정
    • 해당 prop의 용도와 기본 동작을 간단히 주석 또는 문서에 명시
  • src/components/common/dropDown/DropDown.styled.ts
    • $comment 스타일링 로직이 의도한 대로 동작하는지 확인
🤖 Prompt for AI Agents
In src/components/common/dropDown/DropDown.tsx around lines defining
DropDownProps and component usage, add a new optional boolean property comment
to the DropDownProps interface. Set its default value to false either via
defaultProps or default parameter in the component function. Add a brief comment
explaining the purpose of the comment prop. Then verify in
src/components/common/dropDown/DropDown.styled.ts that the $comment styled prop
is correctly handled and applied as intended. This ensures type safety, default
behavior, and clarity for the comment prop used in the DropDown component.

>
<Notification />
</DropDown>
) : (
<img src={bell} alt='알림' />
)}
</S.Alarm> */}
</S.Alarm>
<DropDown
aria-label='프로필 드롭다운'
toggleButton={
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const NotificationItem = ({ item }: NotificationItemProps) => {
return (
<Link to={route} onClick={close}>
<S.Container>
<S.ItemContent>{item.content}</S.ItemContent>
<S.ItemContent>{item.content} | </S.ItemContent>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

구분자 추가 목적은 이해하지만 더 나은 방법을 고려해보세요.

알림 내용 뒤에 구분자를 추가한 목적은 이해하지만, 하드코딩된 문자열 대신 CSS나 스타일드 컴포넌트를 통해 시각적 구분을 구현하는 것을 권장합니다.

CSS pseudo-element를 활용한 대안:

-        <S.ItemContent>{item.content} | </S.ItemContent>
+        <S.ItemContent>{item.content}</S.ItemContent>

그리고 styled 컴포넌트에서:

export const ItemContent = styled.div`
  &::after {
    content: ' | ';
    color: ${({ theme }) => theme.colors.gray};
  }
`;

이 방법의 장점:

  • 스타일과 내용의 분리
  • 테마를 통한 일관된 디자인 관리
  • 향후 구분자 변경 시 중앙화된 관리 가능
🤖 Prompt for AI Agents
In
src/components/common/header/Notification/NotificationItem/NotificationItem.tsx
at line 19, replace the hardcoded delimiter string " | " inside the JSX with a
CSS-based solution using a styled component's ::after pseudo-element. Modify the
styled component for ItemContent to include an ::after rule that adds the
delimiter with appropriate styling and theme color. This separates content from
presentation and centralizes delimiter styling for easier maintenance and
theming.

<S.TypeArea>
<S.Time>{timeAgo(item.createdAt)}</S.Time>
<S.TypeFilter>
Expand Down
4 changes: 2 additions & 2 deletions src/components/user/evaluation/EvaluationContent.styled.ts
Original file line number Diff line number Diff line change
Expand Up @@ -177,10 +177,10 @@ export const CompletedButton = styled.button<{ $active?: boolean }>`
color: ${({ $active }) => ($active ? '#fff' : '#999')};
border: none;
border-radius: 4px;
cursor: ${({ $active }) => ($active ? 'pointer' : 'default')};
cursor: pointer;
transition: background-color 0.2s;

&:hover {
background-color: ${({ $active }) => ($active ? '#2f4a6b' : '#e0e0e0')};
background-color: '#e0e0e0'};
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

CSS 구문 오류를 수정해야 합니다.

hover 스타일에 구문 오류가 있어 컴파일이 실패할 수 있습니다.

다음과 같이 수정하세요:

-    background-color: '#e0e0e0'};
+    background-color: #e0e0e0;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
background-color: '#e0e0e0'};
background-color: #e0e0e0;
🤖 Prompt for AI Agents
In src/components/user/evaluation/EvaluationContent.styled.ts at line 184, there
is a CSS syntax error in the hover style where the background-color property
value is incorrectly enclosed in quotes and followed by a stray semicolon inside
the braces. Remove the quotes around the color value and ensure the line ends
properly without extra characters to fix the syntax and prevent compilation
failure.

}
`;
44 changes: 33 additions & 11 deletions src/components/user/evaluation/EvaluationContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,23 @@ interface EvaluationContentProps {
projectId: number;
projectName: string;
memberList: MemberList[];
isAllEvaluated: boolean;
}

const EvaluationContent = ({
projectId,
projectName,
memberList,
isAllEvaluated,
}: EvaluationContentProps) => {
const {
step,
notDone,
completedMember,
handleClickLeftUser,
handleClickOption,
handleNextStep,
handleCompletedMember,
currentScores,
isNotFill,
} = useEvaluationStep({ projectId, memberList });
Expand All @@ -42,18 +46,26 @@ const EvaluationContent = ({

<S.MainContent>
<S.Header>
<S.Title>{notDone[step]?.nickname}님 평가하기</S.Title>
<S.SubmitButton
size='primary'
schema='primary'
radius='primary'
onClick={handleNextStep}
>
제출하기
</S.SubmitButton>
<S.Title>
{isAllEvaluated
? '평가가 완료 되었습니다. '
: completedMember
? `${completedMember.nickname}님 평가 결과`
: `${notDone[step]?.nickname}님 평가하기`}
</S.Title>
Comment on lines +49 to +55
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

조건부 제목 렌더링 로직 개선 필요

현재 조건부 렌더링 로직이 복잡하고 우선순위가 명확하지 않습니다.

             <S.Title>
-              {isAllEvaluated
-                ? '평가가 완료 되었습니다. '
-                : completedMember
-                ? `${completedMember.nickname}님 평가 결과`
-                : `${notDone[step]?.nickname}님 평가하기`}
+              {(() => {
+                if (completedMember) {
+                  return `${completedMember.nickname}님 평가 결과`;
+                }
+                if (isAllEvaluated) {
+                  return '평가가 완료되었습니다.';
+                }
+                return `${notDone[step]?.nickname}님 평가하기`;
+              })()}
             </S.Title>

이렇게 하면 우선순위가 명확해집니다: 완료된 멤버 선택 > 전체 평가 완료 > 일반 평가 진행

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<S.Title>
{isAllEvaluated
? '평가가 완료 되었습니다. '
: completedMember
? `${completedMember.nickname}님 평가 결과`
: `${notDone[step]?.nickname}님 평가하기`}
</S.Title>
<S.Title>
{(() => {
if (completedMember) {
return `${completedMember.nickname}님 평가 결과`;
}
if (isAllEvaluated) {
return '평가가 완료되었습니다.';
}
return `${notDone[step]?.nickname}님 평가하기`;
})()}
</S.Title>
🤖 Prompt for AI Agents
In src/components/user/evaluation/EvaluationContent.tsx around lines 49 to 55,
the conditional rendering logic for the title is currently complex and the
priority order is unclear. Refactor the logic to clearly prioritize
completedMember first, then isAllEvaluated, and finally the default evaluation
step. This will make the rendering conditions more readable and maintainable by
explicitly checking completedMember before the other conditions.

{!completedMember && (
<S.SubmitButton
size='primary'
schema='primary'
radius='primary'
onClick={handleNextStep}
>
제출하기
</S.SubmitButton>
)}
</S.Header>
<S.MessageContainer>
{isNotFill && (
{isNotFill && completedMember && (
<S.ErrorMessage>모든 질문에 답변해주세요.</S.ErrorMessage>
)}
</S.MessageContainer>
Expand All @@ -78,6 +90,7 @@ const EvaluationContent = ({
handleClickOption(questionNumber, optionValue)
}
value={optionValue + 1}
disabled={!!completedMember}
/>
<S.RadioLabel>{optionValue + 1}</S.RadioLabel>
<S.OptionLabel>{label}</S.OptionLabel>
Expand All @@ -94,7 +107,16 @@ const EvaluationContent = ({
{memberList
.filter((memberData) => memberData.evaluated)
.map((memberData) => (
<S.CompletedButton key={memberData.userId}>
<S.CompletedButton
key={memberData.userId}
onClick={() =>
handleCompletedMember(
memberData.userId,
memberData.nickname,
memberData.scores
)
}
>
{memberData.nickname}
</S.CompletedButton>
))}
Expand Down
Loading