Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
e503eaf
Feat: 스켈레톤 ui 컴포넌트화
lalaurrel Mar 22, 2025
b0f2184
Feat: 애니메이션 추가
lalaurrel Mar 22, 2025
f19e394
Refactor: 로딩중 제거 후 스켈레톤 적용(프로필)
lalaurrel Mar 22, 2025
7921a8a
Fix: 불필요한 주석 삭제
lalaurrel Mar 22, 2025
a09ee4d
Fix: 버튼 조정
lalaurrel Mar 22, 2025
3ccc62d
Fix: 스켈레톤 포스트 4개로 증가
lalaurrel Mar 22, 2025
ba8b981
Fix: ui 수정
lalaurrel Mar 22, 2025
d9c742f
Fix: rem으로 수정
lalaurrel Mar 22, 2025
d74aaaa
FIx: 스타일 분리
lalaurrel Mar 22, 2025
469d80c
Fix: 스타일시트로 분리
lalaurrel Mar 22, 2025
bf74952
Fix: 스타일 삭제
lalaurrel Mar 22, 2025
25a8734
Fix: 보더 둥글게 처리
lalaurrel Mar 22, 2025
236f5af
Fix: 스타일 분리
lalaurrel Mar 22, 2025
3f0aa01
Refactor: profileEdit 스켈레톤 적용
lalaurrel Mar 22, 2025
af367dd
Refactor: AccountSetting 스켈레톤 적용
lalaurrel Mar 22, 2025
c60e366
Refactor: 회원탈퇴 스켈레톤 임시적용
lalaurrel Mar 22, 2025
f35fc1e
Fix: 사소한 UI 수정
lalaurrel Mar 22, 2025
22b5dbc
Refactor: post에 스켈레톤 적용
lalaurrel Mar 22, 2025
ac91e1e
Fix: 로딩타임 수정
lalaurrel Mar 22, 2025
1d329a2
Fix: 스켈레톤 rem으로 변경
lalaurrel Mar 24, 2025
2b5d4ba
Fix: rem으로 변환
lalaurrel Mar 24, 2025
a0a79f6
Merge branch 'dev' into feat/OD-201
lalaurrel Mar 24, 2025
2699906
Merge pull request #140 from oodd-team/feat/OD-201
gustn99 Mar 24, 2025
6dc8812
feat: react-query 설치
mimizae Mar 28, 2025
b8299f3
feat: query를 사용할 수 있도록 비동기 함수로 수정
mimizae Mar 28, 2025
b3bc3bf
doc: 이해를 돕기 위한 주석 추가
mimizae Mar 28, 2025
3ca91e5
chore: 한 번에 불러와지는 페이지 수 조정
mimizae Mar 28, 2025
8f728a1
refactor: 스켈레톤UI 테스트를 위한 setTimeout 제거
gustn99 Mar 29, 2025
86cb993
chore: react-query 설치
gustn99 Mar 29, 2025
6113031
refactor: 게시글 상세 정보 조회 api를 감싸는 react-query 생성
gustn99 Mar 29, 2025
433648c
refactor: 게시글 좋아요 & 취소 api도 react-query를 사용해 구현
gustn99 Mar 29, 2025
e5099d5
refactor: 스켈레톤 UI를 PostBase에 설정
gustn99 Mar 29, 2025
f6bb38f
style: PostBase UI 조정
gustn99 Mar 29, 2025
1f97f2a
Merge pull request #141 from oodd-team/feat/OK-226
gustn99 Mar 29, 2025
a21576c
fix: 병합 충돌 해결
mimizae Mar 29, 2025
4962ec4
Merge pull request #142 from oodd-team/feat/OD-225
gustn99 Mar 29, 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
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
"start:json-server": "json-server --watch db.json --port 5000"
},
"dependencies": {
"@tanstack/react-query": "^5.70.0",
"@tanstack/react-query-devtools": "^5.70.0",
"@types/styled-components": "^5.1.34",
"axios": "^1.7.2",
"dayjs": "^1.11.12",
Expand Down
21 changes: 19 additions & 2 deletions src/apis/post/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { useQuery } from '@tanstack/react-query';

import { newRequest } from '@apis/core';

import type { EmptySuccessResponse } from '@apis/core/dto';
Expand All @@ -17,8 +19,15 @@ export const createPostApi = (data: CreatePostRequest) => newRequest.post<Create

// 게시글 리스트 조회
// 전체 게시글 리스트
export const getPostListApi = (page: number = 1, take: number = 10) =>
newRequest.get<GetPostListResponse>(`/post`, { params: { page, take } });
export const getPostListApi = async ({ pageParam = 1 }) => {
const response = await newRequest.get<GetPostListResponse>('/post', {
params: { page: pageParam, take: 10 },
});
return {
posts: response.data.post,
nextPage: response.data.post.length > 0 ? pageParam + 1 : undefined, // 다음 페이지 여부 확인
};
};
// 유저 게시글 리스트
export const getUserPostListApi = (page: number = 1, take: number = 10, userId: number) =>
newRequest.get<GetUserPostListResponse>(`/post`, { params: { page, take, userId } });
Expand All @@ -36,3 +45,11 @@ export const deletePostApi = (postId: number) => newRequest.delete<EmptySuccessR
// 대표 게시글 지정
export const modifyPostRepresentativeStatusApi = (postId: number) =>
newRequest.patch<EmptySuccessResponse>(`/post/${postId}/is-representative`);

export const usePostDetail = (postId: number) => {
return useQuery({
queryKey: ['postDetail', postId],
queryFn: () => getPostDetailApi(postId),
enabled: !!postId, // postId가 존재할 때만 요청 수행
});
};
37 changes: 37 additions & 0 deletions src/components/Skeleton/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { SkeletonContainer } from './styles';

interface SkeletonProps {
width?: string | number;
height?: string | number;
borderRadius?: string | number;
className?: string;
style?: React.CSSProperties;
}

const Skeleton: React.FC<SkeletonProps> = ({
width = '100%',
height = '16px',
borderRadius = '5px',
className = '',
}) => {
// width와 height가 숫자인 경우 rem 단위를 추가
const getSize = (size: string | number) => {
if (typeof size === 'number') {
return `${size}rem`;
}
return size;
};

return (
<SkeletonContainer
className={className}
style={{
width: getSize(width),
height: getSize(height),
borderRadius: getSize(borderRadius),
}}
/>
);
};

export default Skeleton;
19 changes: 19 additions & 0 deletions src/components/Skeleton/styles.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { styled } from 'styled-components';

export const SkeletonContainer = styled.div`
background-color: #e0e0e0;
position: relative;
overflow: hidden;
background: linear-gradient(90deg, #e0e0e0 0%, #f0f0f0 50%, #e0e0e0 100%);
background-size: 200% 100%;
animation: shimmer 1.5s infinite;

@keyframes shimmer {
0% {
background-position: 200% 0;
}
100% {
background-position: -200% 0;
}
}
`;
19 changes: 13 additions & 6 deletions src/main.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { ReactQueryDevtools } from '@tanstack/react-query-devtools';
import { createRoot } from 'react-dom/client';
import { RecoilRoot } from 'recoil';
import { ThemeProvider } from 'styled-components';
Expand All @@ -10,13 +12,18 @@ import { SocketProvider } from '@context/SocketProvider';

import App from './App';

const queryClient = new QueryClient();

createRoot(document.getElementById('root')!).render(
<ThemeProvider theme={theme}>
<GlobalStyle />
<RecoilRoot>
<SocketProvider>
<App />
</SocketProvider>
</RecoilRoot>
<QueryClientProvider client={queryClient}>
<GlobalStyle />
<RecoilRoot>
<SocketProvider>
<App />
<ReactQueryDevtools initialIsOpen={false} />
</SocketProvider>
</RecoilRoot>
</QueryClientProvider>
</ThemeProvider>,
);
27 changes: 26 additions & 1 deletion src/pages/Account/AccountCancel/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useState } from 'react';
import { useState, useEffect } from 'react';
import { useNavigate } from 'react-router-dom';

import theme from '@styles/theme';
Expand All @@ -11,6 +11,7 @@ import back from '@assets/arrow/left.svg';
import BottomButton from '@components/BottomButton/index';
import { OODDFrame } from '@components/Frame/Frame';
import Modal from '@components/Modal/index';
import Skeleton from '@components/Skeleton';
import { StyledText } from '@components/Text/StyledText';
import TopBar from '@components/TopBar/index';

Expand All @@ -30,8 +31,15 @@ const AccountCancel: React.FC = () => {
const [isChecked, setIsChecked] = useState(false);
const [modalContent, setModalContent] = useState<string | null>(null);
const [isModalVisible, setIsModalVisible] = useState<boolean>(false);
const [isLoading, setIsLoading] = useState(true); // Loading state
const navigate = useNavigate();

useEffect(() => {
setTimeout(() => {
setIsLoading(false);
}, 1000);
}, []);

const handleCheckboxChange = () => {
setIsChecked(!isChecked);
};
Expand Down Expand Up @@ -79,6 +87,23 @@ const AccountCancel: React.FC = () => {
}
};

if (isLoading) {
return (
<OODDFrame>
<CancelContainer>
<TopBar text="회원 탈퇴" LeftButtonSrc={back} onClickLeftButton={() => navigate(-1)} />
<SubTitle>
<StyledText as="div" $textTheme={{ style: 'headline2-medium' }} color={theme.colors.text.primary}>
OOTD 탈퇴 전 확인하세요!
<Skeleton width="100%" height={25} />
</StyledText>
</SubTitle>
</CancelContainer>
<BottomButton content="탈퇴하기" onClick={handleDeleteAccount} disabled={!isChecked} />
</OODDFrame>
);
}

return (
<OODDFrame>
<CancelContainer>
Expand Down
33 changes: 29 additions & 4 deletions src/pages/Account/AccountSetting/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ import leave from '@assets/default/leave.svg';
import Profile_s from '@assets/default/my-page.svg';

import { OODDFrame } from '@components/Frame/Frame';
import Loading from '@components/Loading/index';
import Modal from '@components/Modal';
import Skeleton from '@components/Skeleton';
import { StyledText } from '@components/Text/StyledText';
import TopBar from '@components/TopBar/index';

Expand Down Expand Up @@ -44,8 +44,7 @@ const AccountSetting: React.FC = () => {
setIsLoading(false);
}
};

getUserInfo();
setTimeout(getUserInfo, 1000);
}, []);

const handleConfirmLogout = () => {
Expand All @@ -68,7 +67,33 @@ const AccountSetting: React.FC = () => {
};

if (isLoading) {
return <Loading />;
return (
<OODDFrame>
<ProfileEditContainer>
<TopBar text="계정 관리" LeftButtonSrc={back} onClickLeftButton={() => navigate(-1)} />
<ProfilePicWrapper>
<ProfilePic>
<Skeleton width={7.5} height={7.5} borderRadius={5} />
</ProfilePic>{' '}
<Row>
<Skeleton width="60%" height={1.25} />
</Row>
<Row>
<Skeleton width="100%" height={1.25} />
</Row>
</ProfilePicWrapper>

<List>
<ListItem>
<Skeleton width="100%" height={2.5} />
</ListItem>
<ListItem>
<Skeleton width="100%" height={2.5} />
</ListItem>
</List>
</ProfileEditContainer>
</OODDFrame>
);
}

return (
Expand Down
8 changes: 3 additions & 5 deletions src/pages/Account/AccountSetting/styles.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ export const ProfilePicWrapper = styled.div`
display: flex;
flex-direction: column;
align-items: center;
margin-bottom: 1.25rem;
margin-top: 1.5rem;
`;

export const ProfilePic = styled.div`
Expand All @@ -24,7 +22,6 @@ export const ProfilePic = styled.div`
border-radius: 50%;
overflow: hidden;
margin-top: 2.125rem;
margin-bottom: 1.375rem;

img {
width: 100%;
Expand All @@ -42,7 +39,7 @@ export const Row = styled.div`
justify-content: center;
align-items: center;
width: 100%;
margin-bottom: 0.625rem;
margin-top: 10px;

${Label} {
width: auto;
Expand All @@ -67,7 +64,8 @@ export const List = styled.ul`
export const ListItem = styled.li`
display: flex;
align-items: center;
padding: 0.9375rem 1.25rem;
padding: 15px 10px;

border-bottom: 0px solid ${({ theme }) => theme.colors.background.divider};
cursor: pointer;

Expand Down
Loading