Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FE] staleTime옵션 추가 & 해더 버튼 클릭 이벤트 최적화 & 뉴스 레이아웃 #196

Merged
merged 8 commits into from
Nov 25, 2024
34 changes: 30 additions & 4 deletions FE/src/components/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Link } from 'react-router-dom';
import { Link, useLocation, useNavigate } from 'react-router-dom';
import useAuthStore from 'store/authStore';
import useLoginModalStore from 'store/useLoginModalStore';
import useSearchModalStore from '../store/useSearchModalStore.ts';
Expand All @@ -12,6 +12,8 @@ export default function Header() {
const { isLogin, setIsLogin } = useAuthStore();
const { toggleSearchModal } = useSearchModalStore();
const { searchInput } = useSearchInputStore();
const location = useLocation();
const navigate = useNavigate();

useEffect(() => {
const check = async () => {
Expand All @@ -29,6 +31,13 @@ export default function Header() {
});
};

const handleLink = (to: string) => {
if (location.pathname === to) {
return;
}
navigate(to);
};

Comment on lines +34 to +39
Copy link
Collaborator

Choose a reason for hiding this comment

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

좋습니다! 페이지 이동 작업을 줄일 수 있겠네요 👍👍

return (
<header className='fixed left-0 top-0 h-[60px] w-full bg-white'>
<div className='mx-auto flex h-full max-w-[1280px] items-center justify-between px-8'>
Expand All @@ -39,9 +48,26 @@ export default function Header() {

<div className='flex items-center gap-8'>
<nav className='flex items-center gap-6 text-sm font-bold text-juga-grayscale-500'>
<Link to={'/'}>홈</Link>
<Link to={'/rank'}>랭킹</Link>
{isLogin && <Link to={'/mypage'}>마이페이지</Link>}
<div
onClick={() => handleLink('/')}
className='cursor-pointer px-1 py-2'
>
</div>
<div
onClick={() => handleLink('/rank')}
className='cursor-pointer px-1 py-2'
>
랭킹
</div>
{isLogin && (
<div
onClick={() => handleLink('/mypage')}
className='cursor-pointer px-1 py-2'
>
마이페이지
</div>
)}
</nav>
<div className='relative'>
<input
Expand Down
32 changes: 32 additions & 0 deletions FE/src/components/News/CardWithImage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { NewsMockDataType } from './newsMockData.ts';

type CardWithImageProps = {
data: NewsMockDataType;
};
export default function CardWithImage({ data }: CardWithImageProps) {
return (
<div className='cursor-pointer overflow-hidden rounded-lg'>
{/* 이미지 컨테이너 */}
<div className='relative h-[144px] overflow-hidden'>
<img
src={data.img}
alt='news thumbnail'
className='h-full w-full rounded-lg object-cover transition-transform duration-300 hover:scale-105'
/>
</div>

<div className='flex max-h-[80px] flex-col justify-between gap-1'>
{/* 뉴스 제목 */}
<h3 className='truncate text-left text-base font-semibold text-juga-grayscale-black'>
{data.title}
</h3>

{/* 날짜와 출판사 */}
<div className='flex justify-between text-sm text-juga-grayscale-500'>
<div>{data.date}</div>
<div>{data.publisher}</div>
</div>
</div>
</div>
);
}
12 changes: 12 additions & 0 deletions FE/src/components/News/CardWithoutImage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export default function CardWithoutImage() {
return (
<div className='flex cursor-pointer items-center justify-between hover:underline'>
<span className='truncate text-left text-sm text-juga-grayscale-black'>
[단독] 반도체 산업 신규 투자 확대...정부 지원책 발표
</span>
<span className='whitespace-nowrap text-right text-xs text-juga-grayscale-500'>
중앙일보
</span>
</div>
);
}
27 changes: 27 additions & 0 deletions FE/src/components/News/News.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import CardWithImage from './CardWithImage.tsx';
import CardWithoutImage from './CardWithoutImage.tsx';
import { newsMockData, NewsMockDataType } from './newsMockData.ts';

export default function News() {
return (
<div
className={'items-center, mt-7 flex w-full flex-col justify-center gap-3'}
>
<div className={'flex flex-row'}>
<div className={'text-left text-xl font-bold'}>주요 뉴스</div>
</div>
<ul className='grid grid-cols-1 gap-4 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4'>
{newsMockData.slice(0, 4).map((data: NewsMockDataType) => (
<CardWithImage data={data} key={data.title} />
))}
</ul>

<ul className='mt-5 grid grid-cols-2 gap-3'>
<CardWithoutImage />
<CardWithoutImage />
<CardWithoutImage />
<CardWithoutImage />
</ul>
</div>
);
}
45 changes: 45 additions & 0 deletions FE/src/components/News/newsMockData.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
export type NewsMockDataType = {
publisher: string;
img: string;
title: string;
date: string;
link: string;
};

export const newsMockData: NewsMockDataType[] = [
{
publisher: '중앙일보',
img: 'https://s.pstatic.net/dthumb.phinf/?src=%22https%3A%2F%2Fs.pstatic.net%2Fstatic%2Fnewsstand%2F2024%2F1125%2Farticle_img%2Fnew_main%2F9152%2F071102_001.jpg%22&type=nf312_208&service=navermain',
title: '[단독] 반도체 산업 신규 투자 확대...정부 지원책 발표',
date: '11월 03일 18:55 직접 편집',
link: 'https://www.joongang.co.kr/article/25288962',
},
{
publisher: '동아일보',
img: 'https://s.pstatic.net/dthumb.phinf/?src=%22https%3A%2F%2Fs.pstatic.net%2Fstatic%2Fnewsstand%2F2024%2F1125%2Farticle_img%2Fnew_main%2F9131%2F172557_001.jpg%22&type=nf312_208&service=navermain',
title: '청년 주거대책 발표...월세 지원 확대',
date: '11월 03일 18:39 직접 편집',
link: 'https://www.donga.com/news/article/all/20241103/123456',
},
{
publisher: '한국경제',
img: 'https://s.pstatic.net/dthumb.phinf/?src=%22https%3A%2F%2Fs.pstatic.net%2Fstatic%2Fnewsstand%2F2024%2F1125%2Farticle_img%2Fnew_main%2F9029%2F175118_001.jpg%22&type=nf312_208&service=navermain',
title: '기준금리 동결 전망...시장 영향은?',
date: '11월 03일 17:50 직접 편집',
link: 'https://www.hankyung.com/article/2024110387654',
},
{
publisher: '매일경제',
img: 'https://s.pstatic.net/dthumb.phinf/?src=%22https%3A%2F%2Fs.pstatic.net%2Fstatic%2Fnewsstand%2F2024%2F1125%2Farticle_img%2Fnew_main%2F9243%2F174551_001.jpg%22&type=nf312_208&service=navermain',
title: '글로벌 기업들의 韓 투자 러시...배경은?',
date: '11월 03일 17:30 직접 편집',
link: 'https://www.mk.co.kr/news/2024/11/123987',
},
{
publisher: '한겨레',
img: 'https://s.pstatic.net/static/newsstand/2024/1103/article_img/9005/171525_001.jpg',
title: '환경부, 신재생에너지 정책 전면 개편 추진',
date: '11월 03일 17:15 직접 편집',
link: 'https://www.hani.co.kr/arti/20241103-654321',
},
];
27 changes: 9 additions & 18 deletions FE/src/components/Rank/RankCard.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,11 @@
import { AssetRankItemType, ProfitRankItemType } from './bummyData.ts';
import { RankingItem } from './RankType.ts';

type Props = {
item: ProfitRankItemType | AssetRankItemType;
ranking: number;
item: RankingItem;
type: '수익률순' | '자산순';
};

export default function RankCard({ item, ranking, type }: Props) {
const isProfitRankItem = (
item: ProfitRankItemType | AssetRankItemType,
): item is ProfitRankItemType => {
return 'profitRate' in item;
};

export default function RankCard({ item, type }: Props) {
return (
<div
className={
Expand All @@ -22,29 +15,27 @@ export default function RankCard({ item, ranking, type }: Props) {
<div className='flex items-center gap-2'>
<div
className={`flex h-6 w-6 items-center justify-center rounded-full text-sm font-bold ${
ranking === 0
item.rank === 1
? 'bg-yellow-400 text-white'
: ranking === 1
: item.rank === 2
? 'bg-gray-300 text-white'
: ranking === 2
: item.rank === 3
? 'bg-amber-600 text-white'
: 'bg-gray-100 text-gray-600'
}`}
>
{ranking + 1}
{item.rank}
</div>
<span className='text-sm font-medium'>{item.nickname}</span>
</div>
<div className='text-right'>
<span className='text-sm font-bold text-gray-700'>
{type === '수익률순'
? isProfitRankItem(item)
? `${item.profitRate}%`
: '0%'
? `${item.value}%`
: new Intl.NumberFormat('ko-KR', {
notation: 'compact',
maximumFractionDigits: 1,
}).format((item as AssetRankItemType).totalAsset) + '원'}
}).format((item as RankingItem).value) + '원'}
</span>
</div>
</div>
Expand Down
9 changes: 4 additions & 5 deletions FE/src/components/Rank/RankList.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import RankCard from './RankCard';
import useAuthStore from '../../store/authStore.ts';
import { AssetRankingType, ProfitRankingType } from './bummyData.ts';
import { RankingCategory } from './RankType.ts';

type Props = {
title: '수익률순' | '자산순';
data: ProfitRankingType | AssetRankingType;
data: RankingCategory;
};

export default function RankList({ title, data }: Props) {
Expand All @@ -22,20 +22,19 @@ export default function RankList({ title, data }: Props) {
<RankCard
key={`${item.nickname}-${index}`}
item={item}
ranking={index}
type={title}
/>
))}
</div>
</div>
{isLogin && userRank !== null && typeof userRank.rank === 'number' ? (
{isLogin && userRank !== null ? (
<div className={'w-full rounded-lg bg-white px-2 pb-1 pt-2 shadow-lg'}>
<div className='border-b'>
<h3 className='text-base font-bold text-gray-800'>{`내 ${title} 순위`}</h3>
</div>

<div className={'space-y-1'}>
<RankCard item={userRank} ranking={userRank.rank} type={title} />
<RankCard item={userRank} type={title} />
</div>
</div>
) : null}
Expand Down
13 changes: 12 additions & 1 deletion FE/src/components/Rank/RankType.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,15 @@
export type TmpDataType = {
export type RankingItem = {
nickname: string;
rank: number;
value: number;
};

export type RankingCategory = {
topRank: RankingItem[];
userRank: RankingItem;
};

export type RankingData = {
profitRateRanking: RankingCategory;
assetRanking: RankingCategory;
};
Loading
Loading