Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
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;
}
}
`;
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
31 changes: 31 additions & 0 deletions src/pages/Post/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,18 @@ import { modifyPostRepresentativeStatusApi, deletePostApi } from '@apis/post';
import { isPostRepresentativeAtom, postIdAtom, userAtom } from '@recoil/Post/PostAtom';
import { getCurrentUserId } from '@utils/getCurrentUserId';

import back from '@assets/arrow/left.svg';
import Delete from '@assets/default/delete.svg';
import Edit from '@assets/default/edit.svg';
import Pin from '@assets/default/pin.svg';

import BottomSheet from '@components/BottomSheet';
import BottomSheetMenu from '@components/BottomSheet/BottomSheetMenu';
import OptionsBottomSheet from '@components/BottomSheet/OptionsBottomSheet';
import { OODDFrame } from '@components/Frame/Frame';
import Modal from '@components/Modal';
import Skeleton from '@components/Skeleton';
import TopBar from '@components/TopBar/index';

import type { BottomSheetMenuProps } from '@components/BottomSheet/BottomSheetMenu/dto';
import type { BottomSheetProps } from '@components/BottomSheet/dto';
Expand All @@ -23,6 +27,8 @@ import type { ModalProps } from '@components/Modal/dto';

import PostBase from './PostBase/index';

import { PicWrapper, NameWrapper, InfoWrapper, PostWrapper } from './styles';

const Post: React.FC = () => {
const user = useRecoilValue(userAtom);
const postId = useRecoilValue(postIdAtom);
Expand All @@ -37,6 +43,8 @@ const Post: React.FC = () => {
const [modalContent, setModalContent] = useState('');
const [postPinStatus, setPostPinStatus] = useState<'지정' | '해제'>('지정');

const [isLoading, setIsLoading] = useState(true);

const navigate = useNavigate();
const currentUserId = getCurrentUserId();

Expand Down Expand Up @@ -87,6 +95,10 @@ const Post: React.FC = () => {
};

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

// 현재 게시글이 내 게시글인지 확인
if (user?.id && postId) {
setIsMyPost(currentUserId === user.id);
Expand Down Expand Up @@ -163,6 +175,25 @@ const Post: React.FC = () => {
content: modalContent,
};

if (isLoading) {
return (
<OODDFrame>
<TopBar LeftButtonSrc={back} onClickLeftButton={() => navigate(-1)} />
<InfoWrapper>
<PicWrapper>
<Skeleton width={2.5} height={2.5} borderRadius={2.5} />
</PicWrapper>
<NameWrapper>
<Skeleton width={6.25} height={1.25} />
</NameWrapper>
</InfoWrapper>
<PostWrapper>
<Skeleton width="100%" height={50} />
</PostWrapper>
</OODDFrame>
);
}

return (
<>
<PostBase onClickMenu={handleMenuOpen} />
Expand Down
39 changes: 16 additions & 23 deletions src/pages/Post/styles.tsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,21 @@
import { styled } from 'styled-components';

export const InputLayout = styled.div`
export const InfoWrapper = styled.div`
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
flex-direction: row;
align-items: left;
`;

export const PicWrapper = styled.div`
margin-left: 47px;
`;

export const NameWrapper = styled.div`
margin-left: 10px;
margin-top: 10px;
`;

textarea {
display: block;
width: calc(100% - 3rem);
height: 5.75rem;
border-radius: 0.125rem;
border: 0.0625rem solid ${({ theme }) => theme.colors.gray[600]};
margin-bottom: 5.875rem;
z-index: 2;
margin-top: -3.75rem;
outline: none;
padding: 0.8125rem 0.9375rem;
font-family: 'Pretendard Variable';
font-size: 1rem;
font-style: normal;
font-weight: 300;
line-height: 150%;
color: ${({ theme }) => theme.colors.text.primary};
resize: none;
}
export const PostWrapper = styled.div`
margin-top: 10px;
padding-inline: 30px;
`;
2 changes: 1 addition & 1 deletion src/pages/Profile/ButtonSecondary/styles.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { styled } from 'styled-components';

export const Button = styled.button`
width: 90%;
margin: 1rem auto;
margin: 16px auto;
height: 3.1rem;
text-align: center;
color: ${({ theme }) => theme.colors.brand.primary};
Expand Down
Loading