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
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,26 @@ export default function GatheringListSection({ id }: GatheringListSectionProps)
};

// TODO: μΆ”ν›„ μ—λŸ¬, λ‘œλ”© μˆ˜μ •
if (isLoading) return <p>λ‘œλ”© 쀑...</p>;
if (error) return <p>데이터λ₯Ό λΆˆλŸ¬μ˜€λŠ” 데 μ‹€νŒ¨ν–ˆμŠ΅λ‹ˆλ‹€</p>;
if (!gatheringList || gatheringList.length === 0) return <p>데이터가 μ—†μŠ΅λ‹ˆλ‹€.</p>;
if (isLoading)
return (
<div className="flex items-center justify-center">
<p>λ‘œλ”© 쀑...</p>
</div>
);

if (error)
return (
<div className="flex items-center justify-center">
<p>데이터λ₯Ό λΆˆλŸ¬μ˜€λŠ” 데 μ‹€νŒ¨ν–ˆμŠ΅λ‹ˆλ‹€</p>
</div>
);
Comment on lines +54 to +59
Copy link

Choose a reason for hiding this comment

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

πŸ› οΈ Refactor suggestion

μ—λŸ¬ λ©”μ‹œμ§€λ₯Ό 더 ꡬ체적으둜 ν‘œμ‹œν•΄μ£Όμ„Έμš”

ν˜„μž¬ μ—λŸ¬ λ©”μ‹œμ§€κ°€ λ„ˆλ¬΄ μΌλ°˜μ μž…λ‹ˆλ‹€. μ‚¬μš©μžκ°€ 문제λ₯Ό μ΄ν•΄ν•˜κ³  λŒ€μ²˜ν•  수 μžˆλ„λ‘ 더 ꡬ체적인 정보λ₯Ό μ œκ³΅ν•΄μ•Ό ν•©λ‹ˆλ‹€.

λ‹€μŒκ³Ό 같이 κ°œμ„ ν•΄λ³΄μ„Έμš”:

 if (error)
   return (
     <div className="flex items-center justify-center">
-      <p>데이터λ₯Ό λΆˆλŸ¬μ˜€λŠ” 데 μ‹€νŒ¨ν–ˆμŠ΅λ‹ˆλ‹€</p>
+      <div className="text-center">
+        <p className="text-red-500 mb-2">데이터λ₯Ό λΆˆλŸ¬μ˜€λŠ” 데 μ‹€νŒ¨ν–ˆμŠ΅λ‹ˆλ‹€</p>
+        <p className="text-sm text-gray-600">
+          {error instanceof Error ? error.message : 'μž μ‹œ ν›„ λ‹€μ‹œ μ‹œλ„ν•΄μ£Όμ„Έμš”'}
+        </p>
+      </div>
     </div>
   );
πŸ“ 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
if (error)
return (
<div className="flex items-center justify-center">
<p>데이터λ₯Ό λΆˆλŸ¬μ˜€λŠ” 데 μ‹€νŒ¨ν–ˆμŠ΅λ‹ˆλ‹€</p>
</div>
);
if (error)
return (
<div className="flex items-center justify-center">
<div className="text-center">
<p className="text-red-500 mb-2">데이터λ₯Ό λΆˆλŸ¬μ˜€λŠ” 데 μ‹€νŒ¨ν–ˆμŠ΅λ‹ˆλ‹€</p>
<p className="text-sm text-gray-600">
{error instanceof Error ? error.message : 'μž μ‹œ ν›„ λ‹€μ‹œ μ‹œλ„ν•΄μ£Όμ„Έμš”'}
</p>
</div>
</div>
);

Comment on lines +54 to +59
Copy link

Choose a reason for hiding this comment

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

πŸ› οΈ Refactor suggestion

μ—λŸ¬ μƒνƒœ 처리 κ°œμ„  ν•„μš”

μ—λŸ¬ λ©”μ‹œμ§€κ°€ λ„ˆλ¬΄ 일반적이며, μ‚¬μš©μžμ—κ²Œ μΆ©λΆ„ν•œ μ •λ³΄λ‚˜ ν•΄κ²° 방법을 μ œκ³΅ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

λ‹€μŒκ³Ό 같은 κ°œμ„ μ„ μ œμ•ˆλ“œλ¦½λ‹ˆλ‹€:

-      <div className="flex items-center justify-center">
-        <p>데이터λ₯Ό λΆˆλŸ¬μ˜€λŠ” 데 μ‹€νŒ¨ν–ˆμŠ΅λ‹ˆλ‹€</p>
+      <div className="flex items-center justify-center min-h-[200px]">
+        <div className="flex flex-col items-center gap-4">
+          <p className="text-red-500">데이터λ₯Ό λΆˆλŸ¬μ˜€λŠ” 데 μ‹€νŒ¨ν–ˆμŠ΅λ‹ˆλ‹€</p>
+          <p className="text-sm text-gray-600">{error instanceof Error ? error.message : 'μ•Œ 수 μ—†λŠ” 였λ₯˜κ°€ λ°œμƒν–ˆμŠ΅λ‹ˆλ‹€'}</p>
+          <button
+            onClick={() => window.location.reload()}
+            className="px-4 py-2 bg-primary text-white rounded-md hover:bg-primary-dark"
+          >
+            λ‹€μ‹œ μ‹œλ„
+          </button>
+        </div>
+      </div>
πŸ“ 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
if (error)
return (
<div className="flex items-center justify-center">
<p>데이터λ₯Ό λΆˆλŸ¬μ˜€λŠ” 데 μ‹€νŒ¨ν–ˆμŠ΅λ‹ˆλ‹€</p>
</div>
);
if (error)
return (
<div className="flex items-center justify-center min-h-[200px]">
<div className="flex flex-col items-center gap-4">
<p className="text-red-500">데이터λ₯Ό λΆˆλŸ¬μ˜€λŠ” 데 μ‹€νŒ¨ν–ˆμŠ΅λ‹ˆλ‹€</p>
<p className="text-sm text-gray-600">{error instanceof Error ? error.message : 'μ•Œ 수 μ—†λŠ” 였λ₯˜κ°€ λ°œμƒν–ˆμŠ΅λ‹ˆλ‹€'}</p>
<button
onClick={() => window.location.reload()}
className="px-4 py-2 bg-primary text-white rounded-md hover:bg-primary-dark"
>
λ‹€μ‹œ μ‹œλ„
</button>
</div>
</div>
);


if (!gatheringList || gatheringList.length === 0)
return (
<div className="flex items-center justify-center">
<p>데이터가 μ—†μŠ΅λ‹ˆλ‹€.</p>
</div>
);

return (
<>
Expand Down
61 changes: 22 additions & 39 deletions src/app/(crew)/my-page/_components/profile-card/container.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,44 +15,31 @@ import ProfileCardPresenter from './presenter';
export default function ProfileCard() {
const router = useRouter();
const { isAuth } = useAuth();
const { data: user } = useUser();

// const { rehydrated, setUser } = useAuthStore();
// const [user, setLocalUser] = useState<User | null>(null);
const [isLoading, setIsLoading] = useState(true);
const { data: user, isLoading: userLoading, refetch: refetchUser } = useUser();
const [profileImageUrl, setProfileImageUrl] = useState<string>('');
const [isAuthChecked, setIsAuthChecked] = useState(false);

useEffect(() => {
const checkAuthAndLoadUser = async () => {
// if (!rehydrated) return; // μƒνƒœ 볡원이 μ™„λ£Œλ˜μ§€ μ•Šμ•˜μœΌλ©΄ λŒ€κΈ°

if (!isAuth) {
router.push('/login'); // μΈμ¦λ˜μ§€ μ•Šμ€ 경우 λ¦¬λ””λ ‰μ…˜
return;
}
if (userLoading) return;

setIsLoading(true);

try {
const updatedUser = await fetchUpdatedUser();
// setLocalUser(updatedUser);
// setUser(updatedUser);
setProfileImageUrl(updatedUser.profileImageUrl);
} catch {
toast.error('μœ μ € 정보λ₯Ό κ°€μ Έμ˜€λŠ” 데 μ‹€νŒ¨ν–ˆμŠ΅λ‹ˆλ‹€.');
} finally {
setIsLoading(false);
}
};
if (user) {
setIsAuthChecked(true);
} else if (!isAuth) {
toast.error('둜그인이 ν•„μš”ν•©λ‹ˆλ‹€.');
router.push('/login');
} else {
setIsAuthChecked(true);
}
}, [user, userLoading, isAuth, router]);

checkAuthAndLoadUser();
// }, [isAuth, rehydrated, router, setUser]);
}, [isAuth, router]);
useEffect(() => {
if (user?.profileImageUrl) {
setProfileImageUrl(user.profileImageUrl);
}
}, [user]);

// if (!rehydrated) return null;
if (!isAuth) return null;
if (isLoading) return <div>λ‘œλ”© 쀑...</div>;
if (!user) return <div>μœ μ € 정보λ₯Ό λΆˆλŸ¬μ˜€μ§€ λͺ»ν–ˆμŠ΅λ‹ˆλ‹€.</div>;
if (userLoading || !isAuthChecked) return <div>λ‘œλ”© 쀑...</div>;
if (!user) return null;

const handleEdit = () => {
const input = document.createElement('input');
Expand All @@ -72,10 +59,8 @@ export default function ProfileCard() {
const tempUrl = URL.createObjectURL(file);
setProfileImageUrl(tempUrl);

const updatedUser = await fetchUpdatedUser();
const newProfileImageUrl = `${updatedUser.profileImageUrl}?timestamp=${new Date().getTime()}`;
setProfileImageUrl(newProfileImageUrl);
// setUser({ ...updatedUser, profileImageUrl: newProfileImageUrl });
await refetchUser();
toast.success('ν”„λ‘œν•„ 이미지가 μ—…λ°μ΄νŠΈλ˜μ—ˆμŠ΅λ‹ˆλ‹€.');
Comment on lines +62 to +63
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

파일 μ—…λ‘œλ“œ λ³΄μ•ˆμ„ κ°•ν™”ν•΄μ£Όμ„Έμš”.

파일 크기 검증은 잘 λ˜μ–΄μžˆμ§€λ§Œ, 파일 ν˜•μ‹μ— λŒ€ν•œ μΆ”κ°€ 검증이 ν•„μš”ν•©λ‹ˆλ‹€.

λ‹€μŒκ³Ό 같이 파일 ν˜•μ‹ 검증을 μΆ”κ°€ν•΄μ£Όμ„Έμš”:

    input.onchange = async (event) => {
      const file = (event.target as HTMLInputElement)?.files?.[0];
      if (file) {
+       const validTypes = ['image/jpeg', 'image/png', 'image/jpg'];
+       if (!validTypes.includes(file.type)) {
+         toast.error('PNG, JPG ν˜•μ‹μ˜ μ΄λ―Έμ§€λ§Œ μ—…λ‘œλ“œ κ°€λŠ₯ν•©λ‹ˆλ‹€.');
+         return;
+       }
        if (file.size > 5 * 1024 * 1024) {
          alert('5MB μ΄ν•˜μ˜ 파일만 μ—…λ‘œλ“œ κ°€λŠ₯ν•©λ‹ˆλ‹€.');
          return;
        }

Also applies to: 75-75

} catch (error) {
toast.error('파일 μ—…λ‘œλ“œμ— μ‹€νŒ¨ν–ˆμŠ΅λ‹ˆλ‹€.');
}
Expand All @@ -87,10 +72,8 @@ export default function ProfileCard() {
const handleDeleteProfile = async () => {
try {
await resetUserProfileImage();
const updatedUser = await fetchUpdatedUser();
await refetchUser();
setProfileImageUrl(''); // μ΄ˆκΈ°ν™”λœ 이미지 반영
// setLocalUser(updatedUser);
// setUser(updatedUser);
toast.success('ν”„λ‘œν•„ 이미지가 μ΄ˆκΈ°ν™”λ˜μ—ˆμŠ΅λ‹ˆλ‹€.');
} catch (error) {
toast.error('ν”„λ‘œν•„ 이미지 μ΄ˆκΈ°ν™”μ— μ‹€νŒ¨ν–ˆμŠ΅λ‹ˆλ‹€.');
Expand Down
Loading