Skip to content
Merged
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
35 changes: 31 additions & 4 deletions packages/design-system/src/components/card/RemindCard.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { useEffect, useState } from 'react';
import chippiNoImage from '../../assets/chippi_no_image.svg';
import { Icon } from '../../icons';
import Chip, { ChipColor } from '../chip/Chip';
Expand All @@ -20,17 +21,43 @@ const RemindCard = ({
category,
categoryColor,
imageUrl,
// timeRemaining,
timeRemaining,
onClick,
onOptionsClick,
}: RemindCardProps) => {
const [displayTime, setDisplayTime] = useState('');

useEffect(() => {
const endTime = new Date(timeRemaining).getTime() + 24 * 60 * 60 * 1000;

const updateRemainingTime = () => {
const now = new Date().getTime();
const remainingMilliseconds = endTime - now;

if (remainingMilliseconds <= 0) {
setDisplayTime('시간 만료');
} else {
const totalMinutes = Math.floor(remainingMilliseconds / (1000 * 60));
const hours = Math.floor(totalMinutes / 60);
const minutes = totalMinutes % 60;
setDisplayTime(`${hours}시간 ${minutes}분`);
}
};

const intervalId = setInterval(updateRemainingTime, 60000);

updateRemainingTime();

return () => {
clearInterval(intervalId);
};
Comment on lines +31 to +53
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

날짜 파싱 실패 시 남은 시간이 NaN시간 NaN분으로 깨집니다.

이번 변경은 timeRemaining을 ISO 날짜 문자열이라고 가정하고 new Date(timeRemaining)로 파싱한 뒤 24시간을 더하고 있습니다. 하지만 이 필드가 빈 문자열이거나 기존처럼 "3시간 20분" 같은 표현식 문자열로 넘어오면 Date.parse 결과가 NaN이 되어 UI에 NaN시간 NaN분이 노출됩니다. 실제 백엔드 응답 포맷이 날짜가 아닐 경우 프로덕션에서 바로 재현되는 치명적인 기능 오류입니다. 최소한 파싱 실패 시 기존 문자열을 그대로 보여주는 방어 로직이 필요합니다. 아래와 같이 가드를 추가해 주세요.

-    const endTime = new Date(timeRemaining).getTime() + 24 * 60 * 60 * 1000;
+    const parsed = Date.parse(timeRemaining);
+    if (Number.isNaN(parsed)) {
+      setDisplayTime(timeRemaining ?? '');
+      return;
+    }
+
+    const endTime = parsed + 24 * 60 * 60 * 1000;
📝 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
const endTime = new Date(timeRemaining).getTime() + 24 * 60 * 60 * 1000;
const updateRemainingTime = () => {
const now = new Date().getTime();
const remainingMilliseconds = endTime - now;
if (remainingMilliseconds <= 0) {
setDisplayTime('시간 만료');
} else {
const totalMinutes = Math.floor(remainingMilliseconds / (1000 * 60));
const hours = Math.floor(totalMinutes / 60);
const minutes = totalMinutes % 60;
setDisplayTime(`${hours}시간 ${minutes}분`);
}
};
const intervalId = setInterval(updateRemainingTime, 60000);
updateRemainingTime();
return () => {
clearInterval(intervalId);
};
const parsed = Date.parse(timeRemaining);
if (Number.isNaN(parsed)) {
setDisplayTime(timeRemaining ?? '');
return;
}
const endTime = parsed + 24 * 60 * 60 * 1000;
const updateRemainingTime = () => {
const now = new Date().getTime();
const remainingMilliseconds = endTime - now;
if (remainingMilliseconds <= 0) {
setDisplayTime('시간 만료');
} else {
const totalMinutes = Math.floor(remainingMilliseconds / (1000 * 60));
const hours = Math.floor(totalMinutes / 60);
const minutes = totalMinutes % 60;
setDisplayTime(`${hours}시간 ${minutes}분`);
}
};
const intervalId = setInterval(updateRemainingTime, 60000);
updateRemainingTime();
return () => {
clearInterval(intervalId);
};

}, [timeRemaining]);

return (
<BaseCard onClick={onClick} className="h-[35.6rem]">
<div className="bg-gray900 flex items-center gap-[0.4rem] py-[1.2rem] pl-[1.6rem] text-sm text-white">
<Icon name="ic_clock_active" />
<span className="body2-m text-main400 mr-[0.2rem]">
{/* {timeRemaining || '-'} */}-
</span>
<span className="body2-m text-main400 mr-[0.2rem]">{displayTime}</span>
<span className="body2-m text-white-bg">이후에 사라져요</span>
</div>

Expand Down
Loading