Skip to content

Commit

Permalink
[마이페이지] 내 정보 화면 추가 (#71)
Browse files Browse the repository at this point in the history
* feat: 마이페이지 화면 추가

* feat: 내 프롬프트, 저장한 프롬프트 없을 경우 화면 구현

* style: 마이페이지 화면 레이아웃 스타일 수정

* fix: 닉네임 변경 이후 토스트 워딩 수정

* feat: 닉네임 변경 이후 변경된 닉네임 적용

* style: 저장한 프롬프트 레이아웃 수정

* chore: 오류 수정

* style: 내 정보 페이지 반응형 스타일 수정
  • Loading branch information
hailey-hy authored Dec 18, 2024
1 parent 12f3c53 commit ed66e88
Show file tree
Hide file tree
Showing 14 changed files with 634 additions and 55 deletions.
194 changes: 194 additions & 0 deletions src/assets/svg/ImgEmptyColor.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
import { SVGProps } from "react";

const SvgImgEmptyColor = (props: SVGProps<SVGSVGElement>) => (
<svg
width="148"
height="148"
viewBox="0 0 148 148"
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
>
<circle
cx="74"
cy="74"
r="71.3996"
fill="#F2F3FD"
stroke="white"
stroke-width="5.2009"
/>
<mask
id="mask0_4242_54290"
style={{ maskType: "alpha" }}
maskUnits="userSpaceOnUse"
x="4"
y="4"
width="140"
height="140"
>
<circle cx="73.5976" cy="73.5976" r="69.5761" fill="#F2F3FD" />
</mask>
<g mask="url(#mask0_4242_54290)">
<path
d="M15.1094 75.9336C15.1094 68.2016 21.3774 61.9336 29.1094 61.9336H118.241C125.973 61.9336 132.241 68.2016 132.241 75.9336V127.244C132.241 133.228 127.39 138.079 121.406 138.079H25.9446C19.9605 138.079 15.1094 133.228 15.1094 127.244V75.9336Z"
fill="#7580EA"
/>
<path
d="M50.1532 34.8147C51.1084 30.5009 55.3937 27.7127 59.7246 28.5871L119.614 40.6784C123.837 41.5309 126.505 45.6316 125.574 49.8376L118.602 81.3231L43.2244 66.105L50.1532 34.8147Z"
fill="#D6D9F9"
/>
<mask
id="mask1_4242_54290"
style={{ maskType: "alpha" }}
maskUnits="userSpaceOnUse"
x="15"
y="64"
width="118"
height="75"
>
<path
d="M15.1113 67.6882C15.1113 66.0126 16.4696 64.6543 18.1452 64.6543H129.209C130.885 64.6543 132.243 66.0126 132.243 67.6882V127.245C132.243 133.229 127.392 138.08 121.408 138.08H25.9466C19.9624 138.08 15.1113 133.229 15.1113 127.245V67.6882Z"
fill="#7580EA"
/>
</mask>
<g mask="url(#mask1_4242_54290)">
<path
d="M49.1257 36.4781C50.4392 30.5467 56.3314 26.7129 62.2864 27.9152L116.956 38.9526C122.802 40.133 126.497 45.8108 125.207 51.6344L114.65 99.3113L38.6115 83.9598L49.1257 36.4781Z"
fill="#D6D9F9"
/>
<path
d="M24.9355 51.4785H109.392V98.5872C109.392 104.11 104.915 108.587 99.3921 108.587H34.9355C29.4127 108.587 24.9355 104.11 24.9355 98.5872V51.4785Z"
fill="white"
/>
<g filter="url(#filter0_b_4242_54290)">
<path
d="M15.1094 138.568V72.4844L22.8516 79.0368C31.3481 86.2275 40.6718 92.3793 50.6252 97.3618L132.941 138.568H15.1094Z"
fill="url(#paint0_linear_4242_54290)"
fill-opacity="0.4"
/>
</g>
<g filter="url(#filter1_b_4242_54290)">
<path
d="M132.941 138.568V72.4844L124.479 79.6943C117.181 85.9121 109.165 91.2329 100.601 95.543L15.1102 138.568H132.941Z"
fill="url(#paint1_linear_4242_54290)"
fill-opacity="0.4"
/>
</g>
</g>
<g filter="url(#filter2_b_4242_54290)">
<path
d="M67.6467 94.3138C71.203 91.3015 76.4159 91.3015 79.9723 94.3138L123.002 130.762C129.778 136.501 125.719 147.572 116.839 147.572H30.7796C21.8996 147.572 17.8409 136.501 24.6168 130.762L67.6467 94.3138Z"
fill="#E7E9FF"
fill-opacity="0.62"
/>
</g>
<path
d="M24.9355 47.1953C24.9355 41.1202 29.8604 36.1953 35.9355 36.1953H98.5921C104.557 36.1953 109.392 41.0306 109.392 46.9953V65.1518H24.9355V47.1953Z"
fill="white"
/>
<path
d="M24.9355 47.1953C24.9355 41.1202 29.8604 36.1953 35.9355 36.1953H98.5921C104.557 36.1953 109.392 41.0306 109.392 46.9953V65.1518H24.9355V47.1953Z"
fill="white"
/>
<path
d="M67.9672 49.8691C68.3991 61.902 78.0539 71.5568 90.0868 71.9887C78.0539 72.4206 68.3991 82.0754 67.9672 94.1083C67.5353 82.0754 57.8805 72.4206 45.8477 71.9887C57.8805 71.5568 67.5353 61.902 67.9672 49.8691Z"
fill="#7580EA"
/>
</g>
<defs>
<filter
id="filter0_b_4242_54290"
x="-0.890625"
y="56.4844"
width="149.831"
height="98.084"
filterUnits="userSpaceOnUse"
color-interpolation-filters="sRGB"
>
<feFlood flood-opacity="0" result="BackgroundImageFix" />
<feGaussianBlur in="BackgroundImageFix" stdDeviation="8" />
<feComposite
in2="SourceAlpha"
operator="in"
result="effect1_backgroundBlur_4242_54290"
/>
<feBlend
mode="normal"
in="SourceGraphic"
in2="effect1_backgroundBlur_4242_54290"
result="shape"
/>
</filter>
<filter
id="filter1_b_4242_54290"
x="-0.889648"
y="56.4844"
width="149.831"
height="98.084"
filterUnits="userSpaceOnUse"
color-interpolation-filters="sRGB"
>
<feFlood flood-opacity="0" result="BackgroundImageFix" />
<feGaussianBlur in="BackgroundImageFix" stdDeviation="8" />
<feComposite
in2="SourceAlpha"
operator="in"
result="effect1_backgroundBlur_4242_54290"
/>
<feBlend
mode="normal"
in="SourceGraphic"
in2="effect1_backgroundBlur_4242_54290"
result="shape"
/>
</filter>
<filter
id="filter2_b_4242_54290"
x="10.2256"
y="81.0547"
width="127.168"
height="77.5176"
filterUnits="userSpaceOnUse"
color-interpolation-filters="sRGB"
>
<feFlood flood-opacity="0" result="BackgroundImageFix" />
<feGaussianBlur in="BackgroundImageFix" stdDeviation="5.5" />
<feComposite
in2="SourceAlpha"
operator="in"
result="effect1_backgroundBlur_4242_54290"
/>
<feBlend
mode="normal"
in="SourceGraphic"
in2="effect1_backgroundBlur_4242_54290"
result="shape"
/>
</filter>
<linearGradient
id="paint0_linear_4242_54290"
x1="15.1094"
y1="101.962"
x2="62.6614"
y2="101.962"
gradientUnits="userSpaceOnUse"
>
<stop stop-color="#D3DBFF" />
<stop offset="1" stop-color="#7580EA" />
</linearGradient>
<linearGradient
id="paint1_linear_4242_54290"
x1="132.941"
y1="101.962"
x2="82.9418"
y2="101.962"
gradientUnits="userSpaceOnUse"
>
<stop stop-color="#D2D9FF" />
<stop offset="1" stop-color="#7580EA" />
</linearGradient>
</defs>
</svg>
);

export default SvgImgEmptyColor;
1 change: 1 addition & 0 deletions src/assets/svg/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ export { default as IcInfoCircle } from "./IcInfoCircle";
export { default as ImgEmpty } from "./ImgEmpty";
export { default as Logo } from "./Logo";
export { default as LogoNoLine } from "./LogoNoLine";
export { default as ImgEmptyColor } from "./ImgEmptyColor";
8 changes: 8 additions & 0 deletions src/components/LNB/LNB.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { ReactNode, useEffect, useState } from "react";
import * as Icons from "iconsax-react";
import Icon from "../common/Icon";
import useDeviceSize from "@/hooks/useDeviceSize";
import { useLocation } from "react-router-dom";

export interface MenuItemsType {
key: string;
Expand All @@ -24,6 +25,7 @@ interface LNBtype {
const LNB = ({ menuItems, button, initialMenu = "1" }: LNBtype) => {
const [selectedKey, setSelectedKey] = useState<string>("1");
const { isUnderTablet } = useDeviceSize();
const location = useLocation();

// 메뉴 항목을 동적으로 생성
const desktopItems: MenuProps["items"] = menuItems.map((item) => {
Expand Down Expand Up @@ -57,6 +59,12 @@ const LNB = ({ menuItems, button, initialMenu = "1" }: LNBtype) => {
setSelectedKey(initialMenu);
}, [initialMenu]);

useEffect(() => {
if (location.pathname === "/" && location.state?.resetPromptList) {
setSelectedKey("1");
}
}, [location]);

if (isUnderTablet) {
return (
<Flex
Expand Down
1 change: 1 addition & 0 deletions src/components/common/Input/Input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ const InputContainer = styled.div<{ $length: number; $disabled?: boolean }>`
align-items: center;
padding: 11px 12px;
margin-top: 8px;
flex: 1;
${({ theme }) => theme.fonts.b3_14_reg};
transition: all 0.1s;
Expand Down
30 changes: 30 additions & 0 deletions src/hooks/mutations/usePutNickname.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/**
* 닉네임 변경하기
*/

import { BaseResponse, PUT } from "@/apis/client";
import { useMutation } from "@tanstack/react-query";

interface PutNicknameResponse {
nickname: string;
}

interface PutNicknameProps {
onSuccess: (res: BaseResponse<PutNicknameResponse>) => void;
onError: (e: Error) => void;
}

const updateNickname = async (nickname: string) => {
const { data } = await PUT<PutNicknameResponse>(`/me/nickname`, {
new_nickname: nickname,
});
return data;
};

export const usePutNickname = ({ onSuccess, onError }: PutNicknameProps) => {
return useMutation({
mutationFn: (nickname: string) => updateNickname(nickname),
onSuccess: onSuccess,
onError: onError,
});
};
1 change: 1 addition & 0 deletions src/layouts/Layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ const LayoutContainer = styled.div`
`;

const ContentWrapper = styled.div`
display: flex;
flex: 1; // 남은 공간을 모두 차지하도록 설정
`;

Expand Down
89 changes: 89 additions & 0 deletions src/pages/home/components/Prompt/EmptyPrompt.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import { Flex } from "antd";
import styled from "styled-components";
import Button from "@/components/common/Button/Button";
import Icon from "@/components/common/Icon";
import { ImgEmpty } from "@/assets/svg";
import { ImgEmptyColor } from "@/assets/svg";
import Text from "@/components/common/Text/Text";
import { ViewType } from "@/apis/prompt/prompt.model";
import { useNavigate } from "react-router-dom";

interface EmptyProps {
viewType: ViewType;
}

const EmptyPrompt = ({ viewType }: EmptyProps) => {
const navigate = useNavigate();

if (viewType === "open")
return (
<EmptyWrapper vertical justify="center" align="center" gap={16}>
<ImgEmpty width={148} />

<Flex vertical align="center" gap={2}>
<Text font="b2_16_semi" color="G_700">
아직 등록된 프롬프트가 없어요!
</Text>
<Text font="b3_14_reg" color="G_400">
1등으로 관련 프롬프트를 등록해볼까요?
</Text>
</Flex>
</EmptyWrapper>
);
else if (viewType === "my")
return (
<EmptyWrapper vertical justify="center" align="center" gap={16}>
<Flex vertical align="center" gap={2}>
<Text font="b2_16_semi" color="G_700">
현재 등록한 프롬프트가 없어요
</Text>
<Text
font="b3_14_reg"
color="G_400"
style={{ marginBottom: "16px" }}
>
프롬프트를 등록하면 이곳에 나타나요 <br />
나만의 프롬프트를 등록하러 가볼까요?
</Text>
<Button onClick={() => navigate("/prompt-new")}>
<Icon name="Add" color="white" />
프롬프트 등록
</Button>
</Flex>
</EmptyWrapper>
);
else
return (
<EmptyWrapper vertical justify="center" align="center" gap={16}>
<ImgEmptyColor width={148} />

<Flex vertical justify="center" align="center" gap={2}>
<Text font="b2_16_semi" color="G_700">
즐겨찾는 프롬프트를 추가해
</Text>
<Text font="b2_16_semi" color="G_700">
시간을 절약하세요!
</Text>
<Button
onClick={() =>
navigate("/", { state: { resetPromptList: true } })
}
hierarchy="secondary"
size={44}
style={{ marginTop: "12px" }}
>
프롬프트 둘러보러 가기
</Button>
</Flex>
</EmptyWrapper>
);
};

export default EmptyPrompt;

const EmptyWrapper = styled(Flex)`
width: 100%;
padding: 80px;
border-radius: 8px;
background: ${({ theme }) => theme.colors.G_50};
`;
Loading

0 comments on commit ed66e88

Please sign in to comment.