Skip to content

Commit

Permalink
Merge pull request #274 from prgrms-web-devcourse-final-project/feature/
Browse files Browse the repository at this point in the history
#238

feat: MyPage 컴포넌트 개발
  • Loading branch information
y0unj1NoH authored Dec 6, 2024
2 parents 6f98044 + ebed810 commit f290ae4
Show file tree
Hide file tree
Showing 12 changed files with 231 additions and 57 deletions.
6 changes: 5 additions & 1 deletion src/components/atoms/Button/TextButton/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Text } from "components/atoms/Text";
import { TextButtonWrapper } from "./styled";
import { TextVariant } from "components/atoms/Text";

export interface ITextButtonProps {
/** 버튼에 들어갈 텍스트 */
Expand All @@ -10,12 +11,15 @@ export interface ITextButtonProps {
backgroundColor?: "default" | "transparent";
/** onClick 이벤트*/
onClick?: () => void;
/** Text variant 타입 */
variant?: TextVariant;
}
export const TextButton = ({
text = "",
size = "m",
backgroundColor = "default",
onClick = () => {},
variant = "btn_bold"
}: ITextButtonProps) => {
return (
<TextButtonWrapper
Expand All @@ -24,7 +28,7 @@ export const TextButton = ({
backgroundColor={backgroundColor}
onClick={onClick}
>
<Text content={text} variant="btn_bold"></Text>
<Text content={text} variant={variant}></Text>
</TextButtonWrapper>
);
};
5 changes: 4 additions & 1 deletion src/components/atoms/Text/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
Body1Wrapper,
ButtonWrapper,
TitleBoldWrapper,
TitleSemiBoldWrapper,
DescRegularWrapper,
DescBoldWrapper,
ExplainRegularWrapper,
Expand All @@ -21,6 +22,7 @@ export type TextVariant =
| "body1"
| "button"
| "title_bold"
| "title_semibold"
| "desc_regular"
| "desc_bold"
| "explan_regular"
Expand All @@ -47,6 +49,7 @@ const variantMap: {
body1: Body1Wrapper,
button: ButtonWrapper,
title_bold: TitleBoldWrapper,
title_semibold: TitleSemiBoldWrapper,
desc_regular: DescRegularWrapper,
desc_bold: DescBoldWrapper,
explan_regular: ExplainRegularWrapper,
Expand All @@ -60,7 +63,7 @@ const variantMap: {
export const Text = ({
content,
variant = "body1",
onClick = () => {},
onClick = () => {}
}: ITextProps) => {
const Component = variantMap[variant];
return <Component onClick={onClick}>{content}</Component>;
Expand Down
9 changes: 9 additions & 0 deletions src/components/atoms/Text/styled.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,15 @@ export const TitleBoldWrapper: ReturnType<typeof styled.p> = styled.p`
line-height: ${({ theme }: { theme: ThemeType }) =>
theme.fontStyles.title_bold.height};
`;
export const TitleSemiBoldWrapper: ReturnType<typeof styled.p> = styled.p`
${commonStyles};
font-size: ${({ theme }: { theme: ThemeType }) =>
theme.fontStyles.title_semibold.size};
font-weight: ${({ theme }: { theme: ThemeType }) =>
theme.fontStyles.title_semibold.bold};
line-height: ${({ theme }: { theme: ThemeType }) =>
theme.fontStyles.title_semibold.height};
`;

export const DescRegularWrapper: ReturnType<typeof styled.p> = styled.p`
${commonStyles};
Expand Down
28 changes: 21 additions & 7 deletions src/components/organisms/MyPageMenu/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import { Text } from "components/atoms";
import { IconWithText } from "components/molecules";
import { MY_PAGE_MENUS } from "constants/myPageMenus";
import { MainMenuWrapper, MyPageMenuWrapper, SubMenuWrapper } from "./styled";
import {
MainMenuWrapper,
MyPageMenuWrapper,
SubMenuWrapper,
ColorWrapper,
TextContainer
} from "./styled";

interface IMyPageMenuProps {
/** 메뉴 클릭 시 실행 될 함수 */
Expand All @@ -13,16 +19,24 @@ export const MyPageMenu = ({ onMenuClick }: IMyPageMenuProps) => {
<MyPageMenuWrapper>
{MY_PAGE_MENUS.map(({ title, menus }, idx) => (
<MainMenuWrapper key={`m_root_${idx}`}>
<Text content={title} variant="h5" />
<ColorWrapper>
<Text content={title} variant="title_semibold" />
</ColorWrapper>
<SubMenuWrapper>
{menus.map(({ icon, name, pathname }, i) => (
<IconWithText
{menus.map(({ icon, name, desc, pathname }, i) => (
<TextContainer
key={`m_${idx}_${i}`}
onClick={() => onMenuClick(pathname)}
>
<IconWithText.Icon icon={icon} size="s" />
<IconWithText.Content content={name} />
</IconWithText>
<IconWithText>
<IconWithText.Icon icon={icon} size="s" />
<IconWithText.Content
content={name}
contentVariant="title_semibold"
/>
</IconWithText>
<Text content={desc} variant="explan_regular" />
</TextContainer>
))}
</SubMenuWrapper>
</MainMenuWrapper>
Expand Down
32 changes: 30 additions & 2 deletions src/components/organisms/MyPageMenu/styled.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
import styled from "@emotion/styled";
import { IconWithTextContentWrapper } from "components/molecules/IconWithText/styled";

export const MyPageMenuWrapper: ReturnType<typeof styled.div> = styled.div`
display: flex;
flex-direction: column;
gap: 1rem;
padding: 1rem;
`;

export const MainMenuWrapper: ReturnType<typeof styled.div> = styled.div`
display: flex;
Expand All @@ -12,8 +20,28 @@ export const SubMenuWrapper: ReturnType<typeof styled.div> = styled.div`
gap: 0.25rem;
`;

export const MyPageMenuWrapper: ReturnType<typeof styled.div> = styled.div`
export const ColorWrapper: ReturnType<typeof styled.div> = styled.div`
color: var(--blue-text-blue, #131b53);
`;

export const TextContainer: ReturnType<typeof styled.div> = styled.div`
display: flex;
width: 100%;
padding: 14px 16px;
flex-direction: column;
gap: 1rem;
justify-content: center;
align-items: flex-start;
gap: 6px;
border-radius: 10px;
border: 1px solid var(--grey-field-deactivate, #eceef3);
cursor: pointer; /* 클릭 포인터 추가 */
&:hover {
background-color: #eeeeee;
}
${IconWithTextContentWrapper} {
color: var(--grey-main-text, #2d2d39);
}
`;
23 changes: 19 additions & 4 deletions src/components/organisms/Profile/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
import { Image, Text } from "components/atoms";
import { ProfileWrapper, ImageWrapper, TextWrapper } from "./styled";
import { LinkIcon } from "components/atoms/Icon";
import { IconWithText } from "components/molecules";
import {
ProfileWrapper,
ImageWrapper,
TextWrapper,
TextGuideColor
} from "./styled";

interface IProfileProps {
/** 프로필 이미지 URL */
Expand All @@ -17,10 +24,18 @@ export const Profile = ({ imgUrl, nickname, location }: IProfileProps) => {
<Image type="round" url={imgUrl} />
</ImageWrapper>
<TextWrapper>
<Text content={nickname} variant="h5" />
<Text content={location} variant="body1" />
<IconWithText>
<IconWithText.Content
content={nickname}
contentVariant="title_bold"
/>
{/* TODO: 아이콘 굵기 얇게 수정 */}
<IconWithText.Icon icon={LinkIcon} size="s" />
</IconWithText>
<TextGuideColor>
<Text content={location} variant="explan_regular" />
</TextGuideColor>
</TextWrapper>
</ProfileWrapper>
);
};

19 changes: 15 additions & 4 deletions src/components/organisms/Profile/styled.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,27 @@ import styled from "@emotion/styled";

export const ProfileWrapper: ReturnType<typeof styled.div> = styled.div`
display: flex;
justify-content: flex-start;
padding: 20px 16px;
justify-content: space-between;
align-items: center;
gap: 8px;
align-self: stretch;
border-radius: 10px 10px 0px 0px;
`;

export const ImageWrapper: ReturnType<typeof styled.div> = styled.div`
width: 64px;
`;
width: 100%
aspect-ratio: 1/1;
`;

export const TextWrapper: ReturnType<typeof styled.div> = styled.div`
display: flex;
width: 242px;
flex-direction: column;
align-items: flex-start;
gap: 4px;
`;

export const TextGuideColor: ReturnType<typeof styled.div> = styled.div`
color: #707192;
text-align: center;
`;
28 changes: 23 additions & 5 deletions src/components/templates/MyPageTemplate/index.tsx
Original file line number Diff line number Diff line change
@@ -1,31 +1,49 @@
import { TextButton } from "components/atoms";
import { Profile, MyPageMenu } from "components/organisms";
import { MyPageTemplateWrapper } from "./styled";
import {
MyPageTemplateWrapper,
ProfileContainer,
BackGroundWrapper
} from "./styled";

interface IMyPageTemplateProps {
/** 프로필 이미지 URL */
imgUrl: string;
/** 닉네임 */
nickname: string;
/** 인증한 지역 */
address: string;
location: string;
/** 프로필 수정 버튼 클릭 시 실행될 함수 */
onProfileEditButtonClick: () => void;
/** 메뉴 클릭 시 실행될 함수 */
onMenuClick: (pathname: string) => void;
}

/**
* TODO: 주스탄드의 profile 불러와서, nickname 메뉴에 적용
* @param param0
* @returns
*/

export const MyPageTemplate = ({
imgUrl,
nickname,
address,
location,
onProfileEditButtonClick,
onMenuClick
}: IMyPageTemplateProps) => {
return (
<MyPageTemplateWrapper>
<Profile imgUrl={imgUrl} nickname={nickname} location={address} />
<TextButton text="프로필 수정" onClick={onProfileEditButtonClick} />
<BackGroundWrapper>
<ProfileContainer>
<Profile imgUrl={imgUrl} nickname={nickname} location={location} />
<TextButton
text="프로필 편집"
onClick={onProfileEditButtonClick}
variant="explan_regular"
/>
</ProfileContainer>
</BackGroundWrapper>
<MyPageMenu onMenuClick={onMenuClick} />
</MyPageTemplateWrapper>
);
Expand Down
50 changes: 45 additions & 5 deletions src/components/templates/MyPageTemplate/styled.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,55 @@
import styled from "@emotion/styled";
import { TextButtonWrapper } from "components/atoms/Button/TextButton/styled";
import {
ProfileWrapper,
ImageWrapper
} from "components/organisms/Profile/styled";

export const MyPageTemplateWrapper: ReturnType<typeof styled.div> = styled.div`
position: fixed;
top: 3rem;
left: 0;
display: flex;
width: 100%;
flex-direction: column;
gap: 1rem;
${ImageWrapper} {
width: 80px;
}
${TextButtonWrapper} {
display: flex;
height: 44px;
padding: 12px 16px;
justify-content: space-between;
align-items: center;
align-self: stretch;
border-radius: 0px 0px 10px 10px;
border-top: 1px solid #eceef3;
background: #fff;
margin: 0;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 1;
overflow: hidden;
color: #707192;
text-overflow: ellipsis;
}
${ProfileWrapper} {
background: var(--white, #fff);
}
`;

export const ProfileContainer: ReturnType<typeof styled.div> = styled.div`
display: flex;
width: 100%;
flex-direction: column;
align-items: flex-start;
`;
export const BackGroundWrapper: ReturnType<typeof styled.div> = styled.div`
background: #f4f6f9;
padding: 1rem;
`;

Loading

0 comments on commit f290ae4

Please sign in to comment.