Skip to content

Commit

Permalink
✨ feat: MyPage Skeleton UI 적용.
Browse files Browse the repository at this point in the history
  • Loading branch information
dannysir committed Dec 3, 2024
1 parent eaa7e81 commit fe35690
Show file tree
Hide file tree
Showing 11 changed files with 241 additions and 47 deletions.
14 changes: 5 additions & 9 deletions FE/src/components/Mypage/Account.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,12 @@ import { getAssets } from 'service/assets';
import { isWithinTimeRange } from 'utils/common';

export default function Account() {
const { data, isLoading } = useQuery(
['account', 'assets'],
() => getAssets(),
{
staleTime: 1000,
refetchInterval: isWithinTimeRange('09:00', '15:30') ? 5000 : false,
},
);
const { data } = useQuery(['account', 'assets'], () => getAssets(), {
staleTime: 1000,
refetchInterval: isWithinTimeRange('09:00', '15:30') ? 5000 : false,
suspense: true,
});

if (isLoading) return <div>loading</div>;
if (!data) return <div>No data</div>;

const { asset, stocks } = data;
Expand Down
61 changes: 61 additions & 0 deletions FE/src/components/Mypage/AccountSkeleton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
const AccountConditionSkeleton = () => {
return (
<div className='flex flex-col gap-4 rounded-lg bg-white p-4'>
<div className='flex items-center justify-between'>
{/* 계좌 정보 타이틀 */}
<div className='h-6 w-24 animate-pulse rounded bg-gray-200' />
{/* 날짜 정보 */}
<div className='h-5 w-32 animate-pulse rounded bg-gray-200' />
</div>

<div className='flex flex-col gap-2'>
{/* 총자산, 수익률 등의 정보 */}
<div className='flex items-center justify-between'>
<div className='h-5 w-20 animate-pulse rounded bg-gray-200' />
<div className='h-7 w-32 animate-pulse rounded bg-gray-200' />
</div>
<div className='flex items-center justify-between'>
<div className='h-5 w-20 animate-pulse rounded bg-gray-200' />
<div className='h-7 w-32 animate-pulse rounded bg-gray-200' />
</div>
</div>
</div>
);
};

const MyStocksListSkeleton = () => {
return (
<div className='flex flex-col gap-2 rounded-lg bg-white p-4'>
{/* 보유종목 타이틀 */}
<div className='mb-2 h-6 w-24 animate-pulse rounded bg-gray-200' />

{/* 테이블 헤더 */}
<div className='flex items-center justify-between border-b pb-2'>
<div className='h-4 w-32 animate-pulse rounded bg-gray-200' />
<div className='h-4 w-20 animate-pulse rounded bg-gray-200' />
<div className='h-4 w-24 animate-pulse rounded bg-gray-200' />
</div>

{/* 보유주식 리스트 */}
{Array.from({ length: 5 }).map((_, index) => (
<div
key={index}
className='flex items-center justify-between border-b py-3'
>
<div className='h-5 w-40 animate-pulse rounded bg-gray-200' />
<div className='h-5 w-24 animate-pulse rounded bg-gray-200' />
<div className='h-5 w-28 animate-pulse rounded bg-gray-200' />
</div>
))}
</div>
);
};

export const AccountSkeleton = () => {
return (
<div className='flex min-h-[500px] flex-col gap-3'>
<AccountConditionSkeleton />
<MyStocksListSkeleton />
</div>
);
};
19 changes: 8 additions & 11 deletions FE/src/components/Mypage/BookMark.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,28 +9,25 @@ export default function BookMark() {
navigation(`/stocks/${code}`);
};

const { data, isLoading, isError } = useQuery(
const { data } = useQuery(
['bookmark', 'stock'],
() => getBookmarkedStocks(),
{
staleTime: 1000,
suspense: true,
},
);

if (isLoading) return <div>loading</div>;
if (!data) return <div>No data</div>;
if (isError) return <div>error</div>;

return (
<div className='mx-auto flex min-h-[500px] w-full flex-1 flex-col rounded-md bg-white p-4 shadow-md'>
<div className='flex pb-2 text-sm font-bold border-b'>
<p className='w-1/2 text-left truncate'>종목</p>
<div className='flex border-b pb-2 text-sm font-bold'>
<p className='w-1/2 truncate text-left'>종목</p>
<p className='w-1/4 text-center'>현재가</p>
<p className='w-1/4 text-right'>등락률</p>
</div>

<ul className='flex flex-col text-sm divide-y'>
{data.map((stock) => {
<ul className='flex flex-col divide-y text-sm'>
{data?.map((stock) => {
const { code, name, stck_prpr, prdy_ctrt, prdy_vrss_sign } = stock;

return (
Expand All @@ -39,11 +36,11 @@ export default function BookMark() {
key={code}
onClick={() => handleClick(code)}
>
<div className='flex w-1/2 gap-2 text-left truncate'>
<div className='flex w-1/2 gap-2 truncate text-left'>
<p className='font-semibold'>{name}</p>
<p className='text-gray-500'>{code}</p>
</div>
<p className='w-1/4 text-center truncate'>
<p className='w-1/4 truncate text-center'>
{(+stck_prpr).toLocaleString()}
</p>
<p
Expand Down
39 changes: 39 additions & 0 deletions FE/src/components/Mypage/BookMarkSkeleton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
export const BookmarkSkeleton = () => {
return (
<div className='mx-auto flex min-h-[500px] w-full flex-1 flex-col rounded-md bg-white p-4 shadow-md'>
{/* 헤더 */}
<div className='flex border-b pb-2 text-sm font-bold'>
<div className='w-1/2'>
<div className='h-4 w-16 animate-pulse rounded bg-gray-200' />
</div>
<div className='w-1/4 text-center'>
<div className='mx-auto h-4 w-16 animate-pulse rounded bg-gray-200' />
</div>
<div className='flex w-1/4 justify-end'>
<div className='h-4 w-16 animate-pulse rounded bg-gray-200' />
</div>
</div>

{/* 북마크 리스트 */}
<ul className='flex flex-col divide-y text-sm'>
{Array.from({ length: 8 }).map((_, index) => (
<li key={index} className='flex py-2'>
{/* 종목명과 코드 */}
<div className='flex w-1/2 gap-2'>
<div className='h-4 w-24 animate-pulse rounded bg-gray-200' />
<div className='h-4 w-16 animate-pulse rounded bg-gray-200' />
</div>
{/* 현재가 */}
<div className='flex w-1/4 justify-center'>
<div className='h-4 w-20 animate-pulse rounded bg-gray-200' />
</div>
{/* 등락률 */}
<div className='flex w-1/4 justify-end'>
<div className='h-4 w-16 animate-pulse rounded bg-gray-200' />
</div>
</li>
))}
</ul>
</div>
);
};
30 changes: 14 additions & 16 deletions FE/src/components/Mypage/MyInfo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ import { useEffect, useState } from 'react';

export default function MyInfo() {
const [isEditMode, setIsEditMode] = useState(false);
const { userQuery, updateNickame } = useUser();
const { userQuery, updateNickname } = useUser();

const { data, isLoading, isError } = userQuery;
const { data } = userQuery;

const [nickname, setNickname] = useState('');

Expand All @@ -17,17 +17,13 @@ export default function MyInfo() {
setNickname(data.name);
}, [data]);

if (isLoading) return <div>loading</div>;
if (!data) return <div>No data</div>;
if (isError) return <div>error</div>;

const handeleEditBtnClick = () => {
if (nickname === data.name) {
const handleEditBtnClick = () => {
if (nickname === data?.name) {
setIsEditMode(false);
return;
}

updateNickame.mutate(nickname, {
updateNickname.mutate(nickname, {
onSuccess: (res) => {
if (res.statusCode === 400) {
Toast({ message: res.message, type: 'error' });
Expand All @@ -41,7 +37,7 @@ export default function MyInfo() {
return (
<div className='flex flex-col items-center p-6 text-lg'>
<div className='flex w-full max-w-[600px] items-center gap-2 py-2 sm:w-[80%] lg:w-[50%]'>
<div className='flex items-center justify-between w-full'>
<div className='flex w-full items-center justify-between'>
<p className='w-28 min-w-[80px] truncate font-medium text-juga-grayscale-black sm:min-w-[100px]'>
닉네임
</p>
Expand All @@ -56,17 +52,19 @@ export default function MyInfo() {
autoFocus
/>
<button
onClick={handeleEditBtnClick}
className='w-10 p-1 text-sm font-semibold text-white rounded-lg bg-juga-blue-40'
onClick={handleEditBtnClick}
className='w-10 rounded-lg bg-juga-blue-40 p-1 text-sm font-semibold text-white'
>
수정
</button>
<button
onClick={() => {
setNickname(data.name);
if (data) {
setNickname(data.name);
}
setIsEditMode(false);
}}
className='w-10 p-1 text-sm font-semibold text-white rounded-lg bg-juga-grayscale-500'
className='w-10 rounded-lg bg-juga-grayscale-500 p-1 text-sm font-semibold text-white'
>
취소
</button>
Expand All @@ -76,9 +74,9 @@ export default function MyInfo() {
<p className='min-w-[60px] truncate font-semibold text-juga-grayscale-500 sm:min-w-[80px]'>
{nickname}
</p>
<div className='flex items-center justify-end w-9'>
<div className='flex w-9 items-center justify-end'>
<button onClick={() => setIsEditMode(true)}>
<PencilSquareIcon className='w-5 h-5' />
<PencilSquareIcon className='h-5 w-5' />
</button>
</div>
</>
Expand Down
26 changes: 26 additions & 0 deletions FE/src/components/Mypage/MyInfoSkeleton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
export const MyInfoSkeleton = () => {
return (
<div className='flex flex-col items-center p-6 text-lg'>
<div className='flex w-full max-w-[600px] items-center gap-2 py-2 sm:w-[80%] lg:w-[50%]'>
<div className='flex w-full items-center justify-between'>
{/* 닉네임 라벨 */}
<div className='w-28 min-w-[80px] sm:min-w-[100px]'>
<div className='h-6 w-16 animate-pulse rounded bg-gray-200' />
</div>

<div className='flex items-center gap-2'>
{/* 닉네임 값 */}
<div className='min-w-[60px] sm:min-w-[80px]'>
<div className='h-6 w-24 animate-pulse rounded bg-gray-200' />
</div>

{/* 편집 아이콘 */}
<div className='flex w-9 items-center justify-end'>
<div className='h-5 w-5 animate-pulse rounded bg-gray-200' />
</div>
</div>
</div>
</div>
</div>
);
};
8 changes: 2 additions & 6 deletions FE/src/components/Mypage/Order.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,9 @@ import { formatTimestamp } from 'utils/format';
export default function Order() {
const { orderQuery, removeOrder } = useOrders();

const { data, isLoading, isError } = orderQuery;
const { data } = orderQuery;
const { isOpen, open } = useOrderCancelAlertModalStore();

if (isLoading) return <div>loading</div>;
if (!data) return <div>No data</div>;
if (isError) return <div>error</div>;

return (
<div className='mx-auto flex min-h-[500px] w-full flex-col rounded-md bg-white p-4 shadow-md'>
<div className='flex border-b pb-2 text-sm font-bold'>
Expand All @@ -25,7 +21,7 @@ export default function Order() {
</div>

<ul className='flex flex-col divide-y text-sm'>
{data.map((order) => {
{data?.map((order) => {
const {
id,
stock_code,
Expand Down
58 changes: 58 additions & 0 deletions FE/src/components/Mypage/OrderSkeleton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
export const OrderSkeleton = () => {
return (
<div className='mx-auto flex min-h-[500px] w-full flex-col rounded-md bg-white p-4 shadow-md'>
{/* 헤더 */}
<div className='flex border-b pb-2 text-sm font-bold'>
<div className='w-1/3'>
<div className='h-4 w-16 animate-pulse rounded bg-gray-200' />
</div>
<div className='flex w-1/4 justify-center'>
<div className='h-4 w-16 animate-pulse rounded bg-gray-200' />
</div>
<div className='flex w-1/4 justify-center'>
<div className='h-4 w-16 animate-pulse rounded bg-gray-200' />
</div>
<div className='flex w-1/4 justify-center'>
<div className='h-4 w-20 animate-pulse rounded bg-gray-200' />
</div>
<div className='flex w-1/4 justify-end'>
<div className='h-4 w-20 animate-pulse rounded bg-gray-200' />
</div>
<div className='w-1/6'></div>
</div>

{/* 주문 리스트 */}
<ul className='flex flex-col divide-y text-sm'>
{Array.from({ length: 5 }).map((_, index) => (
<li className='flex py-2' key={index}>
{/* 종목명과 코드 */}
<div className='flex w-1/3 gap-2'>
<div className='h-4 w-24 animate-pulse rounded bg-gray-200' />
<div className='h-4 w-16 animate-pulse rounded bg-gray-200' />
</div>
{/* 요청 유형 */}
<div className='flex w-1/4 justify-center'>
<div className='h-4 w-12 animate-pulse rounded bg-gray-200' />
</div>
{/* 수량 */}
<div className='flex w-1/4 justify-center'>
<div className='h-4 w-16 animate-pulse rounded bg-gray-200' />
</div>
{/* 요청 가격 */}
<div className='flex w-1/4 justify-center'>
<div className='h-4 w-20 animate-pulse rounded bg-gray-200' />
</div>
{/* 요청 시간 */}
<div className='flex w-1/4 justify-end'>
<div className='h-4 w-24 animate-pulse rounded bg-gray-200' />
</div>
{/* 취소 버튼 */}
<div className='flex w-1/6 justify-end'>
<div className='h-6 w-12 animate-pulse rounded-lg bg-gray-200' />
</div>
</li>
))}
</ul>
</div>
);
};
1 change: 1 addition & 0 deletions FE/src/hooks/useOrder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export default function useOrders() {

const orderQuery = useQuery(['account', 'order'], () => getOrders(), {
staleTime: 1000,
suspense: true,
});

const removeOrder = useMutation((id: number) => deleteOrder(id), {
Expand Down
3 changes: 2 additions & 1 deletion FE/src/hooks/useUser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@ export default function useUser() {

const userQuery = useQuery(['myInfo', 'profile'], () => getMyProfile(), {
staleTime: 1000,
suspense: true,
});

const updateNickame = useMutation((nickname: string) => rename(nickname), {
onSuccess: () => queryClient.invalidateQueries(['myInfo', 'profile']),
});

return { userQuery, updateNickame };
return { userQuery, updateNickname: updateNickame };
}
Loading

0 comments on commit fe35690

Please sign in to comment.