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
5 changes: 3 additions & 2 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,10 @@ const protectedRoutes = [
// 인증이 필요 없는 페이지 배열
const publicRoutes = [
{ path: '/login', element: <Login /> },
{ path: '/signup', element: <SignUp /> },
{ path: '/login/complete', element: <LoginComplete /> },
{ path: '/terms-agreement', element: <TermsAgreement /> },

{ path: '/signup', element: <SignUp /> },
{ path: '/signup/terms-agreement', element: <TermsAgreement /> },
];

const App: React.FC = () => {
Expand Down
2 changes: 1 addition & 1 deletion src/components/PostItem/dto.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { UserPostSummary } from '../../apis/post/dto';
import { UserPostSummary } from '@apis/post/dto';

export interface Post extends UserPostSummary {}

Expand Down
38 changes: 16 additions & 22 deletions src/components/PostItem/index.tsx
Original file line number Diff line number Diff line change
@@ -1,46 +1,40 @@
import React from 'react';
import { useNavigate } from 'react-router-dom';
import theme from '../../styles/theme';
import {
PostItemContainer,
PostImageContainer,
PostImage,
LikesCountStyledText,
Icon,
LikesOverlay,
PinSvg,
} from './style';
import HeartSvg from '../../assets/default/like.svg';
import MessageSvg from '../../assets/default/message.svg';
import PinIcon from '../../assets/default/pin.svg';
import { PostItemProps } from './dto';

import theme from '@styles/theme';
import PinIcon from '@assets/default/pin.svg';
import Like from '@components/Icons/Like';
import Message from '@components/Icons/Message';

import type { PostItemProps } from './dto';
import { PostItemLayout, PostImageContainer, PostImage, LikesCountStyledText, LikesOverlay, Pin } from './style';

const PostItem: React.FC<PostItemProps> = ({ post, isMyPost = true }) => {
const navigate = useNavigate();
const imageUrl = post.imageUrl;
const postImageUrl = post.imageUrl;

const handleClick = () => {
const handlePostItemClick = () => {
const path = isMyPost ? `/my-post/${post.id}` : `/post/${post.id}`;
navigate(path);
};

return (
<PostItemContainer onClick={handleClick}>
<PostItemLayout onClick={handlePostItemClick}>
<PostImageContainer>
<PostImage src={imageUrl} alt={`post-${post.id}`} />
{post.isRepresentative && <PinSvg src={PinIcon} />}
<PostImage src={postImageUrl} alt={`post-${post.id}`} />
{post.isRepresentative && <Pin src={PinIcon} />}
<LikesOverlay>
<Icon src={HeartSvg} alt="heart icon" />
<Like />
<LikesCountStyledText $textTheme={{ style: 'caption1-regular' }} color={theme.colors.gray3}>
{post.postLikesCount}
</LikesCountStyledText>
<Icon src={MessageSvg} alt="message icon" />
<Message />
<LikesCountStyledText $textTheme={{ style: 'caption1-regular' }} color={theme.colors.gray3}>
{post.postCommentsCount}
</LikesCountStyledText>
</LikesOverlay>
</PostImageContainer>
</PostItemContainer>
</PostItemLayout>
);
};

Expand Down
6 changes: 3 additions & 3 deletions src/components/PostItem/style.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import styled from 'styled-components';
import { StyledText } from '../Text/StyledText';
import { StyledText } from '@components/Text/StyledText';

export const PostItemContainer = styled.article`
export const PostItemLayout = styled.article`
flex: 1 1 calc(50% - 0.5rem); /* 기본적으로 두 개씩 배치되도록 설정 */
width: 100%;
max-width: 67.5rem; /* 최대 너비 설정 */
Expand Down Expand Up @@ -59,7 +59,7 @@ export const LikesCountStyledText = styled(StyledText)`
margin: 0 8px 0.5rem 4px;
`;

export const PinSvg = styled.img`
export const Pin = styled.img`
display: flex;
position: absolute;
top: 0.75rem;
Expand Down
12 changes: 6 additions & 6 deletions src/components/TopBar/dto.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
export interface TopBarProps {
text?: string; // 텍스트, optional prop
RightButtonSrc?: string; // KebabMenuButton src의 Optional prop
LeftButtonSrc?: string; // BackButton src의 Optional prop
onLeftClick?: () => void; // BackButton src의 Optional prop
onRightClick?: () => void; // KebabMenuButton src의 Optional prop
text?: string;
RightButtonSrc?: string;
LeftButtonSrc?: string;
onClickLeftButton?: () => void;
onClickRightButton?: () => void;
$withBorder?: boolean;
}

export interface TopbarLayoutProps {
export interface TopBarLayoutProps {
$withBorder?: boolean;
}
71 changes: 36 additions & 35 deletions src/components/TopBar/index.tsx
Original file line number Diff line number Diff line change
@@ -1,48 +1,49 @@
import theme from '../../styles/theme';
import { TopbarLayout, StyledTextLayout, LeftButton, RightButton } from './styles';
import React from 'react';
import { useNavigate } from 'react-router-dom';
import { TopBarProps } from './dto';

import theme from '@styles/theme';

import type { TopBarProps } from './dto';
import { TopBarLayout, StyledTextWrapper, LeftButton, RightButton } from './styles';

const TopBar: React.FC<TopBarProps> = ({
text = '',
RightButtonSrc,
LeftButtonSrc,
onLeftClick,
onRightClick,
onClickLeftButton,
onClickRightButton,
$withBorder = false,
}) => {
const nav = useNavigate();
const navigate = useNavigate();

return (
<>
<TopbarLayout $withBorder={$withBorder}>
<LeftButton
src={LeftButtonSrc}
onClick={() => {
if (onLeftClick) {
onLeftClick();
} else {
nav(-1);
}
}}
>
<img src={LeftButtonSrc || ''} alt="뒤로가기" />
</LeftButton>
<StyledTextLayout $textTheme={{ style: 'body1-bold' }} color={theme.colors.black}>
{text}
</StyledTextLayout>
<RightButton
src={RightButtonSrc}
onClick={() => {
if (onRightClick) {
onRightClick();
}
}}
>
<img src={RightButtonSrc} alt="메뉴" />
</RightButton>
</TopbarLayout>
</>
<TopBarLayout $withBorder={$withBorder}>
<LeftButton
src={LeftButtonSrc}
onClick={() => {
if (onClickLeftButton) {
onClickLeftButton();
} else {
navigate(-1);
}
}}
>
<img src={LeftButtonSrc || ''} alt="뒤로가기" />
</LeftButton>
<StyledTextWrapper $textTheme={{ style: 'body1-bold' }} color={theme.colors.black}>
{text}
</StyledTextWrapper>
<RightButton
src={RightButtonSrc}
onClick={() => {
if (onClickRightButton) {
onClickRightButton();
}
}}
>
<img src={RightButtonSrc} alt="메뉴" />
</RightButton>
</TopBarLayout>
);
};

Expand Down
8 changes: 4 additions & 4 deletions src/components/TopBar/styles.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import styled from 'styled-components';
import { TopbarLayoutProps } from './dto';
import { StyledText } from '../Text/StyledText';
import { StyledText } from '@components/Text/StyledText';
import type { TopBarLayoutProps } from './dto';

export const TopbarLayout = styled.header<TopbarLayoutProps>`
export const TopBarLayout = styled.header<TopBarLayoutProps>`
display: flex;
position: sticky;
top: 0; /* 부모 요소의 상단에 붙도록 설정 */
Expand All @@ -18,7 +18,7 @@ export const TopbarLayout = styled.header<TopbarLayoutProps>`
`}
`;

export const StyledTextLayout = styled(StyledText)`
export const StyledTextWrapper = styled(StyledText)`
flex-direction: column;
align-items: center;
`;
Expand Down
5 changes: 5 additions & 0 deletions src/components/UserProfile/dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export interface UserProfileProps {
userImg?: string; // string | undefined
bio?: string;
nickname: string;
}
25 changes: 11 additions & 14 deletions src/components/UserProfile/index.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,23 @@
import React from 'react';
import { StyledText } from '../Text/StyledText';
import theme from '../../styles/theme';
import { UserProfileContainer, UserImg, UserDetails, BioStyledText } from './style';

interface UserProfileProps {
userImg?: string; // string | undefined
bio?: string;
nickname: string;
}
import theme from '@styles/theme';
import { StyledText } from '@components/Text/StyledText';

import type { UserProfileProps } from './dto';
import { UserProfileLayout, UserImg, UserDetailsContainer, StyledBio } from './style';

const UserProfile: React.FC<UserProfileProps> = React.memo(({ userImg, bio = '', nickname }) => {
const truncatedBio = bio ? (bio.length > 50 ? bio.substring(0, 50) + '...' : bio) : '';
return (
<UserProfileContainer>
<UserProfileLayout>
<UserImg src={userImg} alt={`${nickname}'s profile`} />
<UserDetails>
<UserDetailsContainer>
<StyledText $textTheme={{ style: 'headline2-bold' }}>{nickname}</StyledText>
<BioStyledText $textTheme={{ style: 'body2-regular' }} color={theme.colors.gray3}>
<StyledBio $textTheme={{ style: 'body2-regular' }} color={theme.colors.gray3}>
{truncatedBio}
</BioStyledText>
</UserDetails>
</UserProfileContainer>
</StyledBio>
</UserDetailsContainer>
</UserProfileLayout>
);
});

Expand Down
8 changes: 4 additions & 4 deletions src/components/UserProfile/style.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import styled from 'styled-components';
import { StyledText } from '../Text/StyledText';
import { StyledText } from '@components/Text/StyledText';

export const UserProfileContainer = styled.section`
export const UserProfileLayout = styled.section`
display: flex;
flex-direction: row;
`;
Expand All @@ -12,7 +12,7 @@ export const UserImg = styled.img`
border-radius: 50%;
`;

export const UserDetails = styled.section`
export const UserDetailsContainer = styled.section`
display: flex;
flex-direction: column;
justify-content: center;
Expand All @@ -21,7 +21,7 @@ export const UserDetails = styled.section`
margin-left: 1rem;
`;

export const BioStyledText = styled(StyledText)`
export const StyledBio = styled(StyledText)`
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
Expand Down
60 changes: 29 additions & 31 deletions src/pages/AccountCancel/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ import back from '../../assets/arrow/left.svg';

import BottomButton from '../../components/BottomButton';
import { patchUserWithdrawApi } from '../../apis/user';
import Modal from '../../components/Modal';
import Modal from '../../components/Modal';

const AccountCancel: React.FC = () => {
const [isChecked, setIsChecked] = useState(false);
const [modalContent, setModalContent] = useState<string | null>(null);
const [modalContent, setModalContent] = useState<string | null>(null);
const [isModalVisible, setIsModalVisible] = useState<boolean>(false);
const navigate = useNavigate();

Expand Down Expand Up @@ -55,8 +55,8 @@ const AccountCancel: React.FC = () => {
localStorage.clear();

setTimeout(() => {
navigate('/login');
}, 2000);
navigate('/login');
}, 2000);
} else {
setModalContent(response.code || '알 수 없는 오류가 발생했습니다.');
setIsModalVisible(true);
Expand All @@ -71,7 +71,7 @@ const AccountCancel: React.FC = () => {
return (
<OODDFrame>
<CancelContainer>
<TopBar text="회원 탈퇴" LeftButtonSrc={back} onLeftClick={() => navigate(-1)} />
<TopBar text="회원 탈퇴" LeftButtonSrc={back} onClickLeftButton={() => navigate(-1)} />

<SubTitle>
<StyledText as="div" $textTheme={{ style: 'body1-medium', lineHeight: 2 }} color={theme.colors.black}>
Expand All @@ -90,28 +90,27 @@ const AccountCancel: React.FC = () => {
</Text>
<InfoBox>
<InfoItem as="div">
<StyledText
as="div"
$textTheme={{ style: 'body1-medium', lineHeight: 2 }}
color={theme.colors.black}
style={{ whiteSpace: 'nowrap' }} // 줄 바꿈 방지
>
지금까지 OODD를 이용해주셔서 감사합니다!
</StyledText>

<StyledText
as="div"
$textTheme={{ style: 'body1-medium', lineHeight: 2 }}
color={theme.colors.black}
style={{ whiteSpace: 'nowrap' }} // 줄 바꿈 방지
>
지금까지 OODD를 이용해주셔서 감사합니다!
</StyledText>
</InfoItem>
</InfoBox>
<CheckboxWrapper as="div">
<label style={{ display: 'flex', alignItems: 'center', cursor: 'pointer' }}>
<input
type="checkbox"
checked={isChecked}
onChange={handleCheckboxChange}
style={{ marginRight: '8px' }} // 텍스트와 체크박스 간격 조절
/>
<StyledText as="span" $textTheme={{ style: 'body4-light', lineHeight: 1 }} color={theme.colors.gray3}>
안내사항을 모두 확인하였으며, 이에 동의합니다.
</StyledText>
<input
type="checkbox"
checked={isChecked}
onChange={handleCheckboxChange}
style={{ marginRight: '8px' }} // 텍스트와 체크박스 간격 조절
/>
<StyledText as="span" $textTheme={{ style: 'body4-light', lineHeight: 1 }} color={theme.colors.gray3}>
안내사항을 모두 확인하였으며, 이에 동의합니다.
</StyledText>
</label>
</CheckboxWrapper>
</CancelContainer>
Expand All @@ -125,14 +124,13 @@ const AccountCancel: React.FC = () => {
<BottomButton content="탈퇴하기" onClick={handleDeleteAccount} disabled={!isChecked} />
</div>
{isModalVisible && (
<Modal
content={modalContent || ''} // null일 경우 빈 문자열로 처리
onClose={handleModalClose}
isCloseButtonVisible={true}
button={{ content: '확인', onClick: handleModalClose }}
/>
)}

<Modal
content={modalContent || ''} // null일 경우 빈 문자열로 처리
onClose={handleModalClose}
isCloseButtonVisible={true}
button={{ content: '확인', onClick: handleModalClose }}
/>
)}
</OODDFrame>
);
};
Expand Down
Loading
Loading