Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
12 changes: 0 additions & 12 deletions src/components/user/comment/CommentLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,6 @@ import CommentInput from './commentInput/CommentInput';
import LoadingSpinner from '../../common/loadingSpinner/LoadingSpinner';
import useGetComment from '../../../hooks/user/CommentHooks/useGetComment';
import CommentComponentLayout from './commentComponent/CommentComponentLayout';
import Avatar from '../../common/avatar/Avatar';
import { useMyProfileInfo } from '../../../hooks/user/useMyInfo';
import { formatImgPath } from '../../../util/formatImgPath';
import DefaultImg from '../../../assets/defaultImg.png';

interface CommentLayoutProps {
projectId: number;
Expand All @@ -19,15 +15,8 @@ const CommentLayout = ({
createrId,
loginUserId,
}: CommentLayoutProps) => {
const { myData } = useMyProfileInfo();
const { getCommentList, isLoading, isFetching } = useGetComment(projectId);

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;

if (!getCommentList) {
return (
<S.Container>
Expand All @@ -48,7 +37,6 @@ const CommentLayout = ({
</S.CommentCountsContainer>

<S.CommentInput>
<Avatar size='55px' image={profileImg} />
<CommentInput projectId={projectId} commentId={0} />
</S.CommentInput>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,11 @@ export const ReplyContent = styled.p`
`;

export const ReplyInput = styled.div`
width: 100%;
margin-left: 15px;
display: flex;
flex: 1;
width: 94%;
margin-left: 50px;
margin-top: 10px;
margin-bottom: 10px;
`;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,18 +89,17 @@ const CommentComponent = ({
<S.ReplyContent>댓글 달기</S.ReplyContent>
</S.ReplyInputButton>
)}

{activateId === item.id && !onReplyMessage && (
<S.ReplyInput>
<CommentInput
reply={true}
projectId={projectId}
commentId={item.id}
/>
</S.ReplyInput>
)}
</S.CommentWrapper>
</S.Wrapper>
{activateId === item.id && !onReplyMessage && (
<S.ReplyInput>
<CommentInput
reply={true}
projectId={projectId}
commentId={item.id}
/>
</S.ReplyInput>
)}
</S.Container>
);
};
Expand Down
13 changes: 12 additions & 1 deletion src/components/user/comment/commentInput/CommentInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ import usePostReply from '../../../../hooks/user/CommentHooks/usePostReply';
import usePatchReply from '../../../../hooks/user/CommentHooks/usePatchReply';
import usePostComment from '../../../../hooks/user/CommentHooks/usePostComment';
import usePutComment from '../../../../hooks/user/CommentHooks/usePutComment';
import { useMyProfileInfo } from '../../../../hooks/user/useMyInfo';
import { formatImgPath } from '../../../../util/formatImgPath';
import Avatar from '../../../common/avatar/Avatar';
import DefaultImg from '../../../../assets/defaultImg.png';

type FormValue = {
commentInput: string;
Expand Down Expand Up @@ -38,7 +42,7 @@ const CommentInput = ({
register,
setValue,
} = useForm<FormValue>();

const { myData } = useMyProfileInfo();
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

사용자 데이터 로딩에 대한 에러 처리를 확인해주세요.

useMyProfileInfo hook에서 반환하는 데이터가 로딩 중이거나 에러가 발생할 경우에 대한 처리가 필요할 수 있습니다. 현재는 myData만 사용하고 있지만, 로딩 상태나 에러 상태도 고려해보세요.


🏁 Script executed:

#!/bin/bash
# useMyProfileInfo hook의 구현을 확인하여 에러 처리 방식 검토
ast-grep --pattern 'export const useMyProfileInfo = $_'

Length of output: 812


에러 및 로딩 상태 핸들링 추가 필요

현재 useMyProfileInfo 훅이 myDataisLoading만 반환해, 컴포넌트에서 에러 상태를 처리할 수 없습니다. 아래를 참고해 수정하세요.

  • 훅 반환값 확장
    // src/hooks/user/useMyInfo.ts
    export const useMyProfileInfo = () => {
      const isLoggedIn = useAuthStore(state => state.isLoggedIn);
      const { data, isLoading, isError, error } = useQuery<ApiUserInfo>({
        queryKey: myInfoKey.myProfile,
        queryFn: () => getMyInfo(),
        staleTime: Infinity,
        gcTime: Infinity,
        enabled: isLoggedIn,
      });
      return {
        myData: data?.data,
        isLoading,
        isError,
        error,
      };
    };
  • 컴포넌트에서 로딩·에러 처리 추가
    // src/components/user/comment/commentInput/CommentInput.tsx
    const { myData, isLoading, isError, error } = useMyProfileInfo();
    if (isLoading) {
      return <Spinner />;
    }
    if (isError) {
      return <ErrorMessage message={error?.message || '데이터를 불러오는 중 오류가 발생했습니다.'} />;
    }
    // 정상 렌더링...
🤖 Prompt for AI Agents
In src/components/user/comment/commentInput/CommentInput.tsx at line 45, update
the useMyProfileInfo hook usage to also destructure isLoading, isError, and
error states. Add conditional rendering to handle loading and error states by
returning a Spinner component when loading and an ErrorMessage component with
the error message when an error occurs. This ensures proper user feedback during
data fetching issues.

const { isFocused, handleFocus, handleClick } = useInputFocus();
const { createComment } = usePostComment(projectId);
const { changeComment } = usePutComment(projectId, commentId);
Expand All @@ -47,6 +51,12 @@ const CommentInput = ({

const hasInput = Boolean(watch('commentInput', ''));

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;
Comment on lines +54 to +58
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

환경변수 의존성과 이미지 처리 로직을 검증해주세요.

프로필 이미지 URL 생성 로직이 잘 구현되었지만, 몇 가지 확인이 필요합니다:

  1. VITE_APP_IMAGE_CDN_URL 환경변수가 모든 환경에서 정의되어 있는지
  2. formatImgPath 함수가 예상대로 작동하는지
  3. 이미지 로딩 실패 시 기본 이미지로 잘 fallback되는지

🏁 Script executed:

#!/bin/bash
# 환경변수 사용 현황과 formatImgPath 함수 구현 확인
echo "=== 환경변수 사용 현황 ==="
rg -n "VITE_APP_IMAGE_CDN_URL" 

echo "=== formatImgPath 함수 구현 ==="
cat src/util/formatImgPath.ts

Length of output: 713


🏁 Script executed:

#!/bin/bash
# DefaultImg 위치와 사용 맥락 확인
echo "=== DefaultImg 사용 ==="
rg -n "DefaultImg" -A3 src/components

# CommentInput 컴포넌트 내 <img> 태그 및 onError 핸들러 확인
echo "=== CommentInput.tsx <img> ==="
rg -n "<img" -A3 src/components/user/comment/commentInput/CommentInput.tsx

Length of output: 2430


🏁 Script executed:

#!/bin/bash
# avatar 디렉토리 파일 목록 확인
echo "=== avatar 디렉토리 목록 ==="
ls src/components/common/avatar

# Avatar.tsx 구현 확인
echo "=== Avatar.tsx 내용 ==="
cat src/components/common/avatar/Avatar.tsx

# onError 핸들러 확인
echo "=== Avatar.tsx onError 핸들러 ==="
rg -n "onError" -A3 src/components/common/avatar/Avatar.tsx || echo "No onError handler found"

Length of output: 1048


프로필 이미지 URL 생성 및 로딩 실패 대응

  • VITE_APP_IMAGE_CDN_URL는 README.md(64행)에 정의되어 있으며, AvatarList, Header, CommentInput 등에서 일관되게 사용 중입니다.
  • formatImgPath/로 분할 후 slice(3)부터 조합하는 단순 로직으로, 의도한 대로 경로를 추출하고 있습니다.
  • 그러나 <img> 요소에 onError 핸들러가 없어 404 또는 네트워크 오류 시 깨진 이미지가 표시됩니다.

수정 제안:

  • src/components/common/avatar/Avatar.tsx<S.AvatarImg>onError 속성을 추가하여 기본 이미지로 대체 처리하세요.
   <S.AvatarImg
     src={releasedImg}
+    onError={(e) => { e.currentTarget.src = defaultImg; }}
     alt='Avatar'
   />

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In src/components/user/comment/commentInput/CommentInput.tsx around lines 54 to
58, the profile image URL is constructed correctly using the environment
variable and formatImgPath function, but the <img> element lacks an onError
handler to fallback to the default image if loading fails. To fix this, add an
onError event handler to the <img> tag that sets the image source to DefaultImg
upon error, similar to the implementation in
src/components/common/avatar/Avatar.tsx, ensuring broken or missing images
gracefully fallback to the default avatar.


const handleSubmit = (data: { commentInput: string }) => {
if (reply) {
if (activateEditMode) {
Expand Down Expand Up @@ -75,6 +85,7 @@ const CommentInput = ({

return (
<S.InputContainer>
<Avatar size={'55px'} image={profileImg} />
<S.InputWrapper>
<form
onSubmit={
Expand Down