Skip to content
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
1c408df
✨ feat: 아르바이트 시간 포멧팅 함수 추가
Yun-Jinwoo Jun 5, 2025
0adf8b8
✨ feat: 현재로부터 얼마 전인지 계산하는 함수 추가
Yun-Jinwoo Jun 5, 2025
7eee992
✨ feat: 알림 모달창 내에서 각 알림을 나타낼 NotificationCard 컴포넌트 구현
Yun-Jinwoo Jun 5, 2025
ee0200f
✨ feat: props 및 return type에 타입 명시
Yun-Jinwoo Jun 5, 2025
ed74a67
🎨 style: NotificationCard 스타일 추가
Yun-Jinwoo Jun 6, 2025
92d36b8
🖼️ feat: 닫기 아이콘 추가
Yun-Jinwoo Jun 6, 2025
a01886a
✨ feat: NotificationModal 컴포넌트 구현
Yun-Jinwoo Jun 7, 2025
0fd2d63
🎨 style: NotificationCard 스타일링 추가
Yun-Jinwoo Jun 7, 2025
baf166b
🎨 style: index.css에 그림자 스타일변수 추가 및 스크롤바 숨기기 위한 tailwind-scrollbar-hid…
Yun-Jinwoo Jun 7, 2025
e8a93e8
✨ feat: NotificationModal 기능 구현 - 데이터 보여주기
Yun-Jinwoo Jun 7, 2025
c3a9679
🔧 chore: gitignore 수정
Yun-Jinwoo Jun 7, 2025
286cede
Merge remote-tracking branch 'origin/develop' into feat/notification-…
Yun-Jinwoo Jun 7, 2025
3d7ede8
✨ feat: 닫기 버튼 모바일에서만 보이도록 수정 및 닫기 버튼 클릭시 이전 페이지로 이동
Yun-Jinwoo Jun 7, 2025
4ee6e35
✨ feat: type 지정 및 type들 따로 분리
Yun-Jinwoo Jun 7, 2025
bc0d286
🔥 remove: 분리했던 타입들 다시 해당 파일에 위치
Yun-Jinwoo Jun 7, 2025
187474b
📝 docs: 각 파일에 jsDoc 추가하여 문서화
Yun-Jinwoo Jun 7, 2025
2a09bc2
♻️ refactor: data의 타입을 item 안쪽으로 설정
Yun-Jinwoo Jun 8, 2025
4eae6ee
🐛 fix: 근무가 끝나는 시간이 24시 이상인 경우에 대한 처리 추가
Yun-Jinwoo Jun 8, 2025
20c536a
✨ feat: 날짜 형식이 타임스탬프 형식으로 주어질 경우 추가
Yun-Jinwoo Jun 8, 2025
03a3047
Merge branch 'develop' of https://github.com/codeit-6team/The-julge i…
Yun-Jinwoo Jun 9, 2025
c320b43
🎨 style: spacing 관련 수정 (4px -> 1px) 및 버튼 포인터 속성 제거
Yun-Jinwoo Jun 9, 2025
b150026
📝 docs: 주석의 양 좀 줄이기
Yun-Jinwoo Jun 9, 2025
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ node_modules
dist
dist-ssr
*.local
mocks

# Editor directories and files
.vscode/*
Expand Down
10 changes: 10 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"react": "^19.1.0",
"react-dom": "^19.1.0",
"react-router-dom": "^7.6.1",
"tailwind-scrollbar-hide": "^4.0.0",
"tailwindcss": "^4.1.8"
},
"devDependencies": {
Expand Down
Empty file removed src/assets/icons/.gitkeep
Empty file.
10 changes: 10 additions & 0 deletions src/assets/icons/ic_close.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Empty file removed src/components/common/.gitkeep
Empty file.
35 changes: 35 additions & 0 deletions src/components/common/NotificationModal/NotificationCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import type { NotificationCardProps } from '@/types/notification';
import calculateTimeDifference from '@/utils/calculateTimeDefference';
import formatWorkTime from '@/utils/formatWorkTime';

export default function NotificationCard({
status,
restaurantName,
startsAt,
workHour,
createdAt,
}: NotificationCardProps) {
const formattedTime = formatWorkTime({
startsAt,
workHour,
});
const formattedCreatedAt = calculateTimeDifference(createdAt);
const formattedStatus = status === 'accepted' ? '승인' : '거절';
const formattedStatusClass =
status === 'accepted' ? 'text-blue-20' : 'text-red-20';
return (
<div className="flex flex-col gap-1 md:w-[328px] py-4 px-3 bg-white border border-gray-20 rounded-[5px] ">
{status === 'accepted' ? (
<div className="w-[5px] h-[5px] rounded-full bg-blue-20"></div>
) : (
<div className="w-[5px] h-[5px] rounded-full bg-red-20"></div>
)}
<h2 className="text-body2/[22px] font-regular">
{restaurantName} ({formattedTime}) 공고 지원이{' '}
<span className={formattedStatusClass}>{formattedStatus}</span>
되었어요.
</h2>
<p className="text-caption/4 text-gray-40">{formattedCreatedAt}</p>
</div>
);
}
30 changes: 30 additions & 0 deletions src/components/common/NotificationModal/NotificationModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { useNavigate } from 'react-router-dom';
import NotificationCard from './NotificationCard';
import type { NotificationModalProps } from '@/types/notification';
import close from '@/assets/icons/ic_close.svg';

export default function NotificationModal({ data, count }: NotificationModalProps) {
const navigate = useNavigate();
return (
<div className="flex flex-col px-5 py-10 bg-red-10 gap-4 h-screen md:py-6 md:border-1 md:border-gray-30 md:rounded-[10px] md:shadow-custom md:h-[420px] md:w-[368px]">
<div className="flex justify-between items-center">
<h1 className="text-h3 font-bold">알림 {count}개</h1>
<button onClick={()=> navigate(-1)} className="cursor-pointer md:hidden">
<img src={close} alt="닫기" />
</button>
</div>
<div className="flex flex-col gap-2 overflow-y-auto scrollbar-hide">
{data.map((data, index) => (
<NotificationCard
key={index}
status={data.item.result}
restaurantName={data.item.shop.item.name}
startsAt={data.item.notice.item.startsAt}
workHour={data.item.notice.item.workhour}
createdAt={data.item.createdAt}
/>
))}
</div>
</div>
);
}
2 changes: 2 additions & 0 deletions src/index.css
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
@import 'tailwindcss';
@import 'tailwind-scrollbar-hide/v4';

@font-face {
font-family: 'SpoqaHanSansNeo-Regular';
Expand Down Expand Up @@ -90,4 +91,5 @@
--text-body1: 16px;
--text-body2: 14px;
--text-caption: 12px;
--shadow-custom: 0px 2px 8px 0px rgba(120, 116, 134, 0.25);
}
31 changes: 31 additions & 0 deletions src/types/notification.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
export interface NotificationItem {
item: {
createdAt: string;
result: 'accepted' | 'rejected';
read: boolean;
shop: {
item: {
name: string;
};
};
notice: {
item: {
startsAt: string;
workhour: number;
};
};
};
}

export interface NotificationModalProps {
data: NotificationItem[];
count: number;
}

export interface NotificationCardProps {
status: 'accepted' | 'rejected';
restaurantName: string;
startsAt: string;
workHour: number;
createdAt: string;
}
Empty file removed src/utils/.gitkeep
Empty file.
25 changes: 25 additions & 0 deletions src/utils/calculateTimeDefference.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
export default function calculateTimeDifference(createdAt: string): string {
const currentDate = new Date();
const createdDate = new Date(createdAt);

const timeDifference = currentDate.getTime() - createdDate.getTime();
const minutes = Math.floor(timeDifference / (1000 * 60));
const hours = Math.floor(minutes / 60);
const days = Math.floor(hours / 24);
const months = Math.floor(days / 30);
const years = Math.floor(months / 12);

if (minutes < 1) {
return '방금';
} else if (minutes <= 59) {
return `${minutes}분 전`;
} else if (hours <= 23) {
return `${hours}시간 전`;
} else if (days <= 30) {
return `${days}일 전`;
} else if (months <= 11) {
return `${months}달 전`;
} else {
return `${years}년 전`;
Copy link
Collaborator

Choose a reason for hiding this comment

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

~~년 까지 표기로 만드시다니! 좋습니다!!

}
}
22 changes: 22 additions & 0 deletions src/utils/formatWorkTime.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
interface workTime {
startsAt: string;
workHour: number;
}

export default function formatWorkTime({
startsAt,
workHour,
}: workTime): string {
const date = new Date(startsAt);

const kstDate = new Date(date.getTime() + 9 * 60 * 60 * 1000);

const year = kstDate.getFullYear();
const month = String(kstDate.getMonth() + 1).padStart(2, '0');
const day = String(kstDate.getDate()).padStart(2, '0');
const hours = String(kstDate.getHours()).padStart(2, '0');
const afterhours = String(kstDate.getHours() + workHour).padStart(2, '0');
const minutes = String(kstDate.getMinutes()).padStart(2, '0');

return `${year}-${month}-${day} ${hours}:${minutes}~${afterhours}:${minutes} `;
}