Skip to content

Commit

Permalink
✨feat: Home 페이지 더미 데이터 추가 및 메뉴 선택 시 스크롤 기능 구현하기 #9
Browse files Browse the repository at this point in the history
  • Loading branch information
naarang committed Oct 21, 2024
1 parent f206c4d commit 714bf27
Show file tree
Hide file tree
Showing 8 changed files with 146 additions and 54 deletions.
11 changes: 8 additions & 3 deletions src/components/Common/JobPostingCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,17 @@ import CalendarIcon from '@/assets/icons/CalendarIcon.svg?react';
import { JobPostingItemType } from '@/types/common/jobPostingItem';
import { calculateTimeAgo } from '@/utils/calculateTimeAgo';
import { calculateDDay } from '@/utils/calculateDDay';
import { useState } from 'react';

interface JobPostingCardProps {
jobPostingData: JobPostingItemType;
}

const JobPostingCard = ({ jobPostingData }: JobPostingCardProps) => {
const [isBookmarked, setIsBookmarked] = useState<boolean>(
jobPostingData?.is_book_marked ?? false,
);

return (
<article className="flex flex-col gap-[1rem] w-full px-[1.125rem] pt-[1.125rem] pb-[0.75rem] border-[0.5px] border-solid border-[#1E19263D] rounded-[1.125rem]">
<div className="w-full flex justify-between items-start">
Expand Down Expand Up @@ -54,10 +59,10 @@ const JobPostingCard = ({ jobPostingData }: JobPostingCardProps) => {
color="#1E1926"
fontStyle="button-2"
/>
{jobPostingData.is_book_marked ? (
<BookmarkCheckedIcon />
{isBookmarked ? (
<BookmarkCheckedIcon onClick={() => setIsBookmarked(false)} />
) : (
<BookmarkIcon />
<BookmarkIcon onClick={() => setIsBookmarked(true)} />
)}
</div>
</div>
Expand Down
32 changes: 32 additions & 0 deletions src/components/Home/HomeApplicationCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import TopRightArrowIcons from '@/assets/icons/Home/TopRightArrowIcon.svg?react';
import { OngoingInterviewItemType } from '@/types/home/ongoingInterviewItem';

type HomeApplicationCardProps = {
applicationData: OngoingInterviewItemType;
};

const HomeApplicationCard = ({ applicationData }: HomeApplicationCardProps) => {
return (
<article className="flex flex-col gap-[0.5rem] px-[1.25rem] pt-[0.75rem] pb-[1.25rem] min-w-[17.5rem] bg-white rounded-[1rem] shadow-cardShadow">
<div className="w-fit px-[0.438rem] py-[0.125rem] caption-2 bg-[#1E1926] rounded-[0.188rem] text-[#F4F4F9]">
Under the Review
</div>
<div className="w-full flex gap-[1rem] items-center">
<div className='w-[2rem] h-[2rem] rounded-[0.5rem] bg-cover bg-[url("/src/assets/images/JobIconExample.jpeg")]'></div>
<div className="flex-1">
<h5 className="pb-[0.125rem] button-2 text-[#171719]">
{applicationData.title}
</h5>
<p className="caption-1 text-[#BDBDBD]">
{applicationData.address_name}
</p>
</div>
<button className="px-[0.75rem] py-[0.25rem] bg-[#1B1B1B] rounded-[1.313rem]">
<TopRightArrowIcons />
</button>
</div>
</article>
);
};

export default HomeApplicationCard;
62 changes: 27 additions & 35 deletions src/components/Home/HomeApplicationList.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,27 @@
import TopRightArrowIcons from '@/assets/icons/Home/TopRightArrowIcon.svg?react';
import { OngoingInterviewItemType } from '@/types/home/ongoingInterviewItem';
import HomeApplicationCard from '@/components/Home/HomeApplicationCard';

// 진행중인 인터뷰 더미데이터
const ONGOING_INTERVIEW_LIST: OngoingInterviewItemType[] = [
{
id: 12,
icon_img_url: 'aa',
title: '서류 제목이양 야다ㅏ야아닫',
address_name: '주소 주소 주소 주소 주소',
},
{
id: 23,
icon_img_url: 'aa',
title: '서류2',
address_name: '주소 주소 22',
},
{
id: 24,
icon_img_url: 'aa',
title: '서류3',
address_name: '주소 주소 33',
},
];

const HomeApplicationList = () => {
return (
Expand All @@ -7,40 +30,9 @@ const HomeApplicationList = () => {
Ongoing Application
</h3>
<div className="flex gap-[0.5rem] px-[1.25rem] overflow-x-scroll whitespace-nowrap no-scrollbar">
<article className="flex flex-col gap-[0.5rem] px-[1.25rem] pt-[0.75rem] pb-[1.25rem] min-w-[17.5rem] bg-white rounded-[1rem] shadow-cardShadow">
<div className="w-fit px-[0.438rem] py-[0.125rem] caption-2 bg-[#1E1926] rounded-[0.188rem] text-[#F4F4F9]">
Under the Review
</div>
<div className="w-full flex gap-[1rem] items-center">
<div className='w-[2rem] h-[2rem] rounded-[0.5rem] bg-cover bg-[url("/src/assets/images/JobIconExample.jpeg")]'></div>
<div className="flex-1">
<h5 className="pb-[0.125rem] button-2 text-[#171719]">
공고제목
</h5>
<p className="caption-1 text-[#BDBDBD]">장소이름</p>
</div>
<button className="px-[0.75rem] py-[0.25rem] bg-[#1B1B1B] rounded-[1.313rem]">
<TopRightArrowIcons />
</button>
</div>
</article>
<article className="flex flex-col gap-[0.5rem] px-[1.25rem] pt-[0.75rem] pb-[1.25rem] min-w-[17.5rem] bg-white rounded-[1rem] shadow-cardShadow">
<div className="w-fit px-[0.438rem] py-[0.125rem] caption-2 bg-[#1E1926] rounded-[0.188rem] text-[#F4F4F9]">
Under the Review
</div>
<div className="w-full flex gap-[1rem] items-center">
<div className='w-[2rem] h-[2rem] rounded-[0.5rem] bg-cover bg-[url("/src/assets/images/JobIconExample.jpeg")]'></div>
<div className="flex-1">
<h5 className="pb-[0.125rem] button-2 text-[#171719]">
공고제목
</h5>
<p className="caption-1 text-[#BDBDBD]">장소이름</p>
</div>
<button className="px-[0.75rem] py-[0.25rem] bg-[#1B1B1B] rounded-[1.313rem]">
<TopRightArrowIcons />
</button>
</div>
</article>
{ONGOING_INTERVIEW_LIST.map((value: OngoingInterviewItemType) => (
<HomeApplicationCard key={value.id} applicationData={value} />
))}
</div>
</section>
);
Expand Down
38 changes: 31 additions & 7 deletions src/components/Home/HomeJobPostingList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import JobPostingCard from '@/components/Common/JobPostingCard';
import { JobPostingItemType } from '@/types/common/jobPostingItem';
import RightArrowIcon from '@/assets/icons/Home/RightArrowIcon.svg?react';
import Tag from '@/components/Common/Tag';
import { useState } from 'react';
import { useRef, useState } from 'react';

// 공고 목록 더미데이터
const JOB_POSTING_LIST: JobPostingItemType[] = [
Expand Down Expand Up @@ -51,12 +51,27 @@ const enum Menu {
}

const HomeJobPostingList = () => {
const scrollRef = useRef<(HTMLDivElement | null)[]>([]);

const [selectedMenu, setSelectedMenu] = useState<Menu>(Menu.POPULAR);

const scrollToSelectedMenu = (menu: Menu) => {
const scrollIndex: { [key: string]: number } = {
POPULAR: 0,
RECENT: 1,
BOOKMARKS: 2,
};

const target = scrollRef.current[scrollIndex[menu]];
if (!target) return;
target.scrollIntoView({ behavior: 'smooth' });
setSelectedMenu(menu);
};

return (
<section className="w-full bg-[#FEF387]">
<nav className="flex gap-[0.5rem] w-full py-[1rem] px-[2rem] rounded-t-[1rem] bg-white">
<button onClick={() => setSelectedMenu(Menu.POPULAR)}>
<button onClick={() => scrollToSelectedMenu(Menu.POPULAR)}>
<Tag
value={'🔥 Popular'}
padding="0.5rem 1rem"
Expand All @@ -69,7 +84,7 @@ const HomeJobPostingList = () => {
fontStyle="button-2"
/>
</button>
<button onClick={() => setSelectedMenu(Menu.RECENT)}>
<button onClick={() => scrollToSelectedMenu(Menu.RECENT)}>
<Tag
value={'🌟 Recent'}
padding="0.5rem 1rem"
Expand All @@ -81,7 +96,7 @@ const HomeJobPostingList = () => {
/>
</button>
{/* 로그인 시에만 존재하는 메뉴 */}
<button onClick={() => setSelectedMenu(Menu.BOOKMARKS)}>
<button onClick={() => scrollToSelectedMenu(Menu.BOOKMARKS)}>
<Tag
value={'🌟 Bookmarks'}
padding="0.5rem 1rem"
Expand All @@ -96,7 +111,10 @@ const HomeJobPostingList = () => {
</button>
</nav>
<div className="flex flex-col gap-[3.125rem] pt-[0.75rem] pb-[6.25rem] px-[1.5rem] bg-white">
<div className="flex flex-col gap-[1rem]">
<div
className="flex flex-col gap-[1rem]"
ref={(e) => (scrollRef.current[0] = e)}
>
<div className="flex justify-between items-end">
<h3 className="head-3 text-black">🔥 Popular Job Lists for You</h3>
<button className="flex items-center gap-[0.625rem] button-2 text-[#1E1926]">
Expand All @@ -107,7 +125,10 @@ const HomeJobPostingList = () => {
<JobPostingCard key={value.id} jobPostingData={value} />
))}
</div>
<div className="flex flex-col gap-[1rem]">
<div
className="flex flex-col gap-[1rem]"
ref={(e) => (scrollRef.current[1] = e)}
>
<div className="flex justify-between items-end">
<h3 className="head-3 text-black">🌟 Recently Added Job</h3>
<button className="flex items-center gap-[0.625rem] button-2 text-[#1E1926]">
Expand All @@ -118,7 +139,10 @@ const HomeJobPostingList = () => {
<JobPostingCard key={value.id} jobPostingData={value} />
))}
</div>
<div className="flex flex-col gap-[1rem]">
<div
className="flex flex-col gap-[1rem]"
ref={(e) => (scrollRef.current[2] = e)}
>
<div className="flex justify-between items-end">
<h3 className="head-3 text-black">🌟 My Bookmarks</h3>
<button className="flex items-center gap-[0.625rem] button-2 text-[#1E1926]">
Expand Down
25 changes: 22 additions & 3 deletions src/components/Home/HomeRecommendPost.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,22 @@
import MessageIcon from '@/assets/icons/Home/MessageIcon.svg?react';
import HomeRecommendPostCard from '@/components/Home/HomeRecommendPostCard';
import { RecommendJobPostingItemType } from '@/types/home/recommendJobPostingItem';

// 추천 공고 목록 더미데이터
const RECOMMEND_JOB_POSTING_LIST: RecommendJobPostingItemType[] = [
{
id: 1,
title: '공고 제목1',
recruitment_dead_line: '2024.11.01',
job_category: 'GENERAL_INTERPRETATION_TRANSLATION',
},
{
id: 2,
title: '공고 제목 222 어쩌구 저쩌구',
recruitment_dead_line: '2024.10.25',
job_category: 'GENERAL_CAFE',
},
];

const HomeRecommendPost = () => {
const hasProfile = true; // 이력서 등록여부
Expand All @@ -8,9 +25,11 @@ const HomeRecommendPost = () => {
{hasProfile ? (
// 이력서 등록 -> 추천 공고 보여주기
<>
<HomeRecommendPostCard />
<HomeRecommendPostCard />
<HomeRecommendPostCard />
{RECOMMEND_JOB_POSTING_LIST.map(
(value: RecommendJobPostingItemType) => (
<HomeRecommendPostCard key={value.id} jobPostingData={value} />
),
)}
</>
) : (
// 이력서 미등록 -> 추가 메뉴 보여주기
Expand Down
20 changes: 14 additions & 6 deletions src/components/Home/HomeRecommendPostCard.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,22 @@
import MessageIcon from '@/assets/icons/Home/MessageIcon.svg?react';
import { RecommendJobPostingItemType } from '@/types/home/recommendJobPostingItem';
import { calculateDDay } from '@/utils/calculateDDay';

const HomeRecommendPostCard = () => {
interface HomeRecommendPostCardProps {
jobPostingData: RecommendJobPostingItemType;
}

const HomeRecommendPostCard = ({
jobPostingData,
}: HomeRecommendPostCardProps) => {
return (
<article className="flex flex-col justify-between min-w-[11.25rem] w-[11.25rem] h-[8.75rem] pt-[0.75rem] pb-[1.125rem] px-[1.125rem] rounded-[1.5rem] border-[0.031rem] border-[#F4F4F9] shadow-cardShadow bg-[#F4F4F9]">
<div className="flex justify-end gap-[0.375rem]">
<div className="py-[0.125rem] px-[0.438rem] border-[0.031rem] border-[#1E1926] rounded-[0.5rem] bg-[#FFFFFFCC] text-[#1E1926] caption-2">
D-day
<div className="h-fit py-[0.125rem] px-[0.438rem] border-[0.031rem] border-[#1E1926] rounded-[0.5rem] bg-[#FFFFFFCC] text-[#1E1926] caption-2">
{calculateDDay(jobPostingData.recruitment_dead_line)}
</div>
<div className="py-[0.125rem] px-[0.438rem] border-[0.031rem] border-[#1E1926] rounded-[0.5rem] bg-[#1E1926] text-[#F4F4F9] caption-2">
업직종
<div className="h-fit py-[0.125rem] px-[0.438rem] border-[0.031rem] border-[#1E1926] rounded-[0.5rem] bg-[#1E1926] text-[#F4F4F9] caption-2 break-keep whitespace-normal">
{jobPostingData.job_category.replace(/_/g, ' ').toLowerCase()}
</div>
</div>
<MessageIcon />
Expand All @@ -17,7 +25,7 @@ const HomeRecommendPostCard = () => {
한은서님을 위한 추천 공고 도착!
</p>
<div className="button-2 text-[#1E1926] break-keep whitespace-normal">
공고제목) 에그드랍 역삼역점 파트 알바 모집
공고제목{')'} {jobPostingData.title}
</div>
</div>
</article>
Expand Down
6 changes: 6 additions & 0 deletions src/types/home/ongoingInterviewItem.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export type OngoingInterviewItemType = {
id: number;
icon_img_url: string;
title: string;
address_name: string;
};
6 changes: 6 additions & 0 deletions src/types/home/recommendJobPostingItem.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export type RecommendJobPostingItemType = {
id: number;
title: string; // 공고 제목
recruitment_dead_line: string; // 마감일자
job_category: string; // “업직종종류",
};

0 comments on commit 714bf27

Please sign in to comment.