diff --git a/src/App.tsx b/src/App.tsx
index e7907ab..8cff189 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -2,6 +2,9 @@ import React from 'react';
import { Route, Routes } from 'react-router-dom';
import { Home, Write, InputPage, Temp, NoPage } from 'pages';
import Post from 'pages/post';
+import My from 'pages/my';
+import Edit from 'pages/my/edit';
+import Cancle from 'pages/my/cancle';
function App() {
return (
@@ -12,6 +15,9 @@ function App() {
} />
} />
} />
+ } />
+ } />
+ } />
);
}
diff --git a/src/components/Modal/ImageChange/index.tsx b/src/components/Modal/ImageChange/index.tsx
new file mode 100644
index 0000000..05a9f01
--- /dev/null
+++ b/src/components/Modal/ImageChange/index.tsx
@@ -0,0 +1,34 @@
+import React from 'react';
+import * as S from './style';
+import XIcon from 'svg/XIcon';
+import ChangeIcon from 'svg/ChangeIcon';
+
+interface Props {
+ onClose: () => void;
+}
+
+const ImageChange = ({ onClose }: Props) => {
+ return (
+
+
+
+ 프로필 변경
+
+
+
+
+
+
+
+
+ 확인
+
+ );
+};
+
+export default ImageChange;
diff --git a/src/components/Modal/ImageChange/style.ts b/src/components/Modal/ImageChange/style.ts
new file mode 100644
index 0000000..5e498f0
--- /dev/null
+++ b/src/components/Modal/ImageChange/style.ts
@@ -0,0 +1,73 @@
+import styled from '@emotion/styled';
+
+export const Wrapper = styled.div`
+ display: flex;
+ width: 400px;
+ padding: 24px;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ gap: 28px;
+ background-color: ${({ theme }) => theme.color.white};
+ border-radius: 8px;
+`;
+
+export const Header = styled.div`
+ display: flex;
+ justify-content: space-between;
+ align-items: flex-start;
+ align-self: stretch;
+ background-color: ${({ theme }) => theme.color.white};
+`;
+
+export const CloseButton = styled.div``;
+
+export const Title = styled.div`
+ ${({ theme }) => theme.fontStyle.m1.semi};
+ color: ${({ theme }) => theme.color.black};
+`;
+
+export const Hidden = styled.input`
+ display: none;
+`;
+
+export const ChangeButton = styled.div`
+ position: absolute;
+ top: 0;
+ right: 0;
+ width: 40px;
+ height: 40px;
+ border-radius: 0px 8px;
+ background: ${({ theme }) => theme.color.gray[400]};
+ display: flex;
+ justify-content: center;
+ align-items: center;
+`;
+
+export const ImageBack = styled.div`
+ position: relative;
+ width: 352px;
+ height: 345px;
+ border-radius: 8px;
+ background: ${({ theme }) => theme.color.gray[300]};
+`;
+
+export const CheckButton = styled.div`
+ padding: 10px 16px;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ align-self: stretch;
+ gap: 10px;
+ border-radius: 8px;
+ background-color: ${({ theme }) => theme.color.main};
+ color: ${({ theme }) => theme.color.white};
+ ${({ theme }) => theme.fontStyle.m3.semi};
+`;
+
+export const ProfileContainer = styled.div`
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 16px;
+`;
diff --git a/src/components/My/CanclePage/PostHeader/index.tsx b/src/components/My/CanclePage/PostHeader/index.tsx
new file mode 100644
index 0000000..f8e5444
--- /dev/null
+++ b/src/components/My/CanclePage/PostHeader/index.tsx
@@ -0,0 +1,20 @@
+import React from 'react';
+import * as S from './style';
+import { LeftArrow } from 'svg';
+import { useNavigate } from 'react-router-dom';
+
+const PostHeader = () => {
+ const navigate = useNavigate();
+
+ return (
+
+ navigate(`/my`)}>
+
+
+ 글보기
+
+
+ );
+};
+
+export default PostHeader;
diff --git a/src/components/My/CanclePage/PostHeader/style.ts b/src/components/My/CanclePage/PostHeader/style.ts
new file mode 100644
index 0000000..8f1cf5a
--- /dev/null
+++ b/src/components/My/CanclePage/PostHeader/style.ts
@@ -0,0 +1,24 @@
+import styled from '@emotion/styled';
+
+export const Container = styled.div`
+ max-width: 37.5rem;
+ width: 100%;
+ padding: 1rem 0.75rem;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+`;
+
+export const HomeButton = styled.div`
+ cursor: pointer;
+`;
+
+export const Text = styled.p`
+ ${({ theme }) => theme.fontStyle.m2}
+ color: ${({ theme }) => theme.color.gray[500]};
+`;
+
+export const Empty = styled.div`
+ width: 24px;
+ height: 25px;
+`;
diff --git a/src/components/My/CanclePage/PostProfile/index.tsx b/src/components/My/CanclePage/PostProfile/index.tsx
new file mode 100644
index 0000000..f8bb444
--- /dev/null
+++ b/src/components/My/CanclePage/PostProfile/index.tsx
@@ -0,0 +1,36 @@
+import React, { useState } from 'react';
+import * as S from './style';
+import KebabIcon from 'svg/KebabIcon';
+
+const PostProfile = () => {
+ const [modal, setModal] = useState(false);
+ return (
+
+
+
+
+ 한재형
+
+ 광주소프트웨어마이스터고등학교
+
+ 1학년
+
+ 여자
+
+
+
+
+ setModal(!modal)}>
+
+
+ {modal && (
+
+ 글 삭제
+
+ )}
+
+
+ );
+};
+
+export default PostProfile;
diff --git a/src/components/My/CanclePage/PostProfile/style.ts b/src/components/My/CanclePage/PostProfile/style.ts
new file mode 100644
index 0000000..98ced9e
--- /dev/null
+++ b/src/components/My/CanclePage/PostProfile/style.ts
@@ -0,0 +1,75 @@
+import styled from '@emotion/styled';
+
+export const Wrapper = styled.div`
+ display: flex;
+ justify-content: space-between;
+`;
+
+export const Profile = styled.div`
+ display: flex;
+ align-items: center;
+ gap: 0.75rem;
+`;
+
+export const ProfileImg = styled.img`
+ width: 3rem;
+ height: 3rem;
+ border-radius: 100%;
+`;
+
+export const ProfileText = styled.div`
+ display: flex;
+ flex-direction: column;
+ gap: 0.125rem;
+`;
+
+export const Name = styled.span`
+ ${({ theme }) => theme.fontStyle.label};
+ color: ${({ theme }) => theme.color.gray[600]};
+`;
+
+export const Data = styled.div`
+ display: flex;
+ align-items: center;
+ gap: 0.25rem;
+`;
+
+export const DataText = styled.span`
+ ${({ theme }) => theme.fontStyle.label};
+ color: ${({ theme }) => theme.color.gray[500]};
+`;
+
+export const Dot = styled.div`
+ width: 0.25rem;
+ height: 0.25rem;
+ border-radius: 0.125rem;
+ background-color: #b4b5b7;
+`;
+
+export const ModalContainer = styled.div`
+ position: relative;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+`;
+
+export const DetailButton = styled.div``;
+
+export const DetailModal = styled.div`
+ position: absolute;
+ left: -78px;
+ top: 40px;
+ display: inline-flex;
+ padding: 24px;
+ flex-direction: column;
+ align-items: flex-start;
+ gap: 32px;
+ border-radius: 8px;
+ background: ${({ theme }) => theme.color.white};
+ box-shadow: 0px 0px 20px 0px rgba(0, 0, 0, 0.08);
+`;
+
+export const WarningText = styled.div`
+ ${({ theme }) => theme.fontStyle.m3.reg}
+ color: ${({ theme }) => theme.color.system};
+`;
diff --git a/src/components/My/CanclePage/index.tsx b/src/components/My/CanclePage/index.tsx
new file mode 100644
index 0000000..be0ac3b
--- /dev/null
+++ b/src/components/My/CanclePage/index.tsx
@@ -0,0 +1,55 @@
+import React, { useState } from 'react';
+import * as S from './style';
+import Profile from './PostProfile';
+import MateList from 'components/MateList';
+import { ReportIcon } from 'svg';
+import { DeclarationModal } from 'components/Modal';
+import TagList from '../PostList/PostCard/TagList';
+import PostHeader from './PostHeader';
+
+const CanclePage = () => {
+ const [modal, setModal] = useState(false);
+ return (
+ <>
+
+
+
+
+
+
+ 같이 산책 하실 분 구해요
+
+ 토요일에 호수공원 산책할 사람토요일에 호수공원 산책할
+ 사람토요일에 호수공원 산책할 사람토요일에 호수공원 산책할
+ 사람토요일에 호수공원 산책할 사람토요일에 호수공원 산책할
+ 사람토요일에 호수공원 산책할 사람토요일에 호수공원 산책할
+ 사람토요일에 호수공원 산책할 사람토요일에 호수공원 산책할
+ 사람토요일에 호수공원 산책할 사람토요일에 호수공원 산책할 사람
+
+
+
+ 카톡 : wjdtjffl55
+ 디스코드 : hye_2417
+ 인스타그램 : hye_2417
+
+ 마감일 : 2024년 06월 17일
+
+ 2자리 남음
+
+
+
+ setModal(true)}>
+
+
+
+
+
+
+ 신청 취소
+
+ {modal && setModal(false)} postId={1} />}
+ >
+ );
+};
+
+export default CanclePage;
diff --git a/src/components/My/CanclePage/style.ts b/src/components/My/CanclePage/style.ts
new file mode 100644
index 0000000..285833a
--- /dev/null
+++ b/src/components/My/CanclePage/style.ts
@@ -0,0 +1,142 @@
+import styled from '@emotion/styled';
+
+export const Container = styled.div`
+ padding: 1.75rem 1.5rem;
+ max-width: 37.5rem;
+ width: 100%;
+ display: flex;
+ flex-direction: column;
+ gap: 2.5rem;
+ border: 1px solid ${({ theme }) => theme.color.gray[100]};
+ border-radius: 0.5rem;
+`;
+
+export const PostContainer = styled.div`
+ width: 100%;
+ display: flex;
+ flex-direction: column;
+ gap: 1.75rem;
+`;
+
+export const ApplyContainer = styled.div`
+ display: flex;
+ flex-direction: column;
+ gap: 20px;
+`;
+
+export const PostText = styled.div`
+ display: flex;
+ flex-direction: column;
+ gap: 8px;
+`;
+
+export const Title = styled.div`
+ ${({ theme }) => theme.fontStyle.h4.semi}
+ color: ${({ theme }) => theme.color.black};
+`;
+
+export const Content = styled.div`
+ ${({ theme }) => theme.fontStyle.m3.reg}
+ color: ${({ theme }) => theme.color.black};
+`;
+
+export const SNSContainer = styled.div`
+ display: flex;
+ flex-direction: column;
+ gap: 0.25rem;
+`;
+
+export const SNSText = styled(Content)``;
+
+export const Deadline = styled(Content)``;
+
+export const PostData = styled.div`
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ gap: 1rem;
+`;
+
+export const Remain = styled.span`
+ ${({ theme }) => theme.fontStyle.m3.reg}
+ color: ${({ theme }) => theme.color.gray[500]};
+`;
+
+export const TagReportContainer = styled.div`
+ display: flex;
+ justify-content: space-between;
+`;
+
+export const ReportButton = styled.div`
+ cursor: pointer;
+`;
+
+export const CancleButton = styled.button`
+ ${({ theme }) => theme.fontStyle.m3.semi};
+ color: ${({ theme }) => theme.color.white};
+ border: none;
+ border-radius: 0.5rem;
+ background: ${({ theme }) => theme.color.system};
+ display: flex;
+ padding: 0.75rem 1.75rem;
+ justify-content: center;
+ align-items: center;
+ gap: 0.625rem;
+ cursor: pointer;
+`;
+
+export const Line = styled.div`
+ background: ${({ theme }) => theme.color.gray[200]};
+`;
+
+export const ApplicantList = styled.div`
+ display: flex;
+ width: 600px;
+ flex-direction: column;
+ gap: 28px;
+`;
+
+export const ApplicantContainer = styled.div`
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+`;
+
+export const ProfileText = styled.div`
+ display: flex;
+ gap: 8px;
+`;
+
+export const Name = styled.span`
+ ${({ theme }) => theme.fontStyle.m2.semi};
+ color: ${({ theme }) => theme.color.black};
+`;
+
+export const Data = styled.div`
+ display: flex;
+ align-items: center;
+ gap: 0.25rem;
+`;
+
+export const DataText = styled.span`
+ ${({ theme }) => theme.fontStyle.label};
+ color: ${({ theme }) => theme.color.gray[500]};
+`;
+
+export const Dot = styled.div`
+ width: 0.25rem;
+ height: 0.25rem;
+ border-radius: 0.125rem;
+ background-color: #b4b5b7;
+`;
+
+export const OutButton = styled.div`
+ display: flex;
+ padding: 8px 12px;
+ justify-content: center;
+ align-items: center;
+ gap: 10px;
+ border-radius: 8px;
+ background: ${({ theme }) => theme.color.system};
+ color: ${({ theme }) => theme.color.white};
+`;
diff --git a/src/components/My/DetailPost/PostHeader/index.tsx b/src/components/My/DetailPost/PostHeader/index.tsx
new file mode 100644
index 0000000..f8e5444
--- /dev/null
+++ b/src/components/My/DetailPost/PostHeader/index.tsx
@@ -0,0 +1,20 @@
+import React from 'react';
+import * as S from './style';
+import { LeftArrow } from 'svg';
+import { useNavigate } from 'react-router-dom';
+
+const PostHeader = () => {
+ const navigate = useNavigate();
+
+ return (
+
+ navigate(`/my`)}>
+
+
+ 글보기
+
+
+ );
+};
+
+export default PostHeader;
diff --git a/src/components/My/DetailPost/PostHeader/style.ts b/src/components/My/DetailPost/PostHeader/style.ts
new file mode 100644
index 0000000..8f1cf5a
--- /dev/null
+++ b/src/components/My/DetailPost/PostHeader/style.ts
@@ -0,0 +1,24 @@
+import styled from '@emotion/styled';
+
+export const Container = styled.div`
+ max-width: 37.5rem;
+ width: 100%;
+ padding: 1rem 0.75rem;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+`;
+
+export const HomeButton = styled.div`
+ cursor: pointer;
+`;
+
+export const Text = styled.p`
+ ${({ theme }) => theme.fontStyle.m2}
+ color: ${({ theme }) => theme.color.gray[500]};
+`;
+
+export const Empty = styled.div`
+ width: 24px;
+ height: 25px;
+`;
diff --git a/src/components/My/DetailPost/PostProfile/index.tsx b/src/components/My/DetailPost/PostProfile/index.tsx
new file mode 100644
index 0000000..f8bb444
--- /dev/null
+++ b/src/components/My/DetailPost/PostProfile/index.tsx
@@ -0,0 +1,36 @@
+import React, { useState } from 'react';
+import * as S from './style';
+import KebabIcon from 'svg/KebabIcon';
+
+const PostProfile = () => {
+ const [modal, setModal] = useState(false);
+ return (
+
+
+
+
+ 한재형
+
+ 광주소프트웨어마이스터고등학교
+
+ 1학년
+
+ 여자
+
+
+
+
+ setModal(!modal)}>
+
+
+ {modal && (
+
+ 글 삭제
+
+ )}
+
+
+ );
+};
+
+export default PostProfile;
diff --git a/src/components/My/DetailPost/PostProfile/style.ts b/src/components/My/DetailPost/PostProfile/style.ts
new file mode 100644
index 0000000..98ced9e
--- /dev/null
+++ b/src/components/My/DetailPost/PostProfile/style.ts
@@ -0,0 +1,75 @@
+import styled from '@emotion/styled';
+
+export const Wrapper = styled.div`
+ display: flex;
+ justify-content: space-between;
+`;
+
+export const Profile = styled.div`
+ display: flex;
+ align-items: center;
+ gap: 0.75rem;
+`;
+
+export const ProfileImg = styled.img`
+ width: 3rem;
+ height: 3rem;
+ border-radius: 100%;
+`;
+
+export const ProfileText = styled.div`
+ display: flex;
+ flex-direction: column;
+ gap: 0.125rem;
+`;
+
+export const Name = styled.span`
+ ${({ theme }) => theme.fontStyle.label};
+ color: ${({ theme }) => theme.color.gray[600]};
+`;
+
+export const Data = styled.div`
+ display: flex;
+ align-items: center;
+ gap: 0.25rem;
+`;
+
+export const DataText = styled.span`
+ ${({ theme }) => theme.fontStyle.label};
+ color: ${({ theme }) => theme.color.gray[500]};
+`;
+
+export const Dot = styled.div`
+ width: 0.25rem;
+ height: 0.25rem;
+ border-radius: 0.125rem;
+ background-color: #b4b5b7;
+`;
+
+export const ModalContainer = styled.div`
+ position: relative;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+`;
+
+export const DetailButton = styled.div``;
+
+export const DetailModal = styled.div`
+ position: absolute;
+ left: -78px;
+ top: 40px;
+ display: inline-flex;
+ padding: 24px;
+ flex-direction: column;
+ align-items: flex-start;
+ gap: 32px;
+ border-radius: 8px;
+ background: ${({ theme }) => theme.color.white};
+ box-shadow: 0px 0px 20px 0px rgba(0, 0, 0, 0.08);
+`;
+
+export const WarningText = styled.div`
+ ${({ theme }) => theme.fontStyle.m3.reg}
+ color: ${({ theme }) => theme.color.system};
+`;
diff --git a/src/components/My/DetailPost/index.tsx b/src/components/My/DetailPost/index.tsx
new file mode 100644
index 0000000..2eb3888
--- /dev/null
+++ b/src/components/My/DetailPost/index.tsx
@@ -0,0 +1,75 @@
+import React, { useState } from 'react';
+import * as S from './style';
+import Profile from './PostProfile';
+import MateList from 'components/MateList';
+import { ReportIcon } from 'svg';
+import { DeclarationModal } from 'components/Modal';
+import TagList from '../PostList/PostCard/TagList';
+import PostHeader from './PostHeader';
+
+const DetailPost = () => {
+ const [modal, setModal] = useState(false);
+ return (
+ <>
+
+
+
+
+
+
+ 같이 산책 하실 분 구해요
+
+ 토요일에 호수공원 산책할 사람토요일에 호수공원 산책할
+ 사람토요일에 호수공원 산책할 사람토요일에 호수공원 산책할
+ 사람토요일에 호수공원 산책할 사람토요일에 호수공원 산책할
+ 사람토요일에 호수공원 산책할 사람토요일에 호수공원 산책할
+ 사람토요일에 호수공원 산책할 사람토요일에 호수공원 산책할
+ 사람토요일에 호수공원 산책할 사람토요일에 호수공원 산책할 사람
+
+
+
+ 카톡 : wjdtjffl55
+ 디스코드 : hye_2417
+ 인스타그램 : hye_2417
+
+ 마감일 : 2024년 06월 17일
+
+ 2자리 남음
+
+
+
+ setModal(true)}>
+
+
+
+
+
+
+ 글 수정
+ {
+
+
+ {[...Array(3)].map((_, idx) => (
+
+
+ 한재형
+
+ 광주소프트웨어마이스터고등학교
+
+ 1학년
+
+ 여자
+
+
+ 내보내기
+
+ ))}
+
+ }
+
+ {modal && setModal(false)} postId={1} />}
+ >
+ );
+};
+
+export default DetailPost;
diff --git a/src/components/My/DetailPost/style.ts b/src/components/My/DetailPost/style.ts
new file mode 100644
index 0000000..9eb5e50
--- /dev/null
+++ b/src/components/My/DetailPost/style.ts
@@ -0,0 +1,142 @@
+import styled from '@emotion/styled';
+
+export const Container = styled.div`
+ padding: 1.75rem 1.5rem;
+ max-width: 37.5rem;
+ width: 100%;
+ display: flex;
+ flex-direction: column;
+ gap: 2.5rem;
+ border: 1px solid ${({ theme }) => theme.color.gray[100]};
+ border-radius: 0.5rem;
+`;
+
+export const PostContainer = styled.div`
+ width: 100%;
+ display: flex;
+ flex-direction: column;
+ gap: 1.75rem;
+`;
+
+export const ApplyContainer = styled.div`
+ display: flex;
+ flex-direction: column;
+ gap: 20px;
+`;
+
+export const PostText = styled.div`
+ display: flex;
+ flex-direction: column;
+ gap: 8px;
+`;
+
+export const Title = styled.div`
+ ${({ theme }) => theme.fontStyle.h4.semi}
+ color: ${({ theme }) => theme.color.black};
+`;
+
+export const Content = styled.div`
+ ${({ theme }) => theme.fontStyle.m3.reg}
+ color: ${({ theme }) => theme.color.black};
+`;
+
+export const SNSContainer = styled.div`
+ display: flex;
+ flex-direction: column;
+ gap: 0.25rem;
+`;
+
+export const SNSText = styled(Content)``;
+
+export const Deadline = styled(Content)``;
+
+export const PostData = styled.div`
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ gap: 1rem;
+`;
+
+export const Remain = styled.span`
+ ${({ theme }) => theme.fontStyle.m3.reg}
+ color: ${({ theme }) => theme.color.gray[500]};
+`;
+
+export const TagReportContainer = styled.div`
+ display: flex;
+ justify-content: space-between;
+`;
+
+export const ReportButton = styled.div`
+ cursor: pointer;
+`;
+
+export const EditButton = styled.button`
+ ${({ theme }) => theme.fontStyle.m3.semi};
+ color: ${({ theme }) => theme.color.white};
+ border: none;
+ border-radius: 0.5rem;
+ background: ${({ theme }) => theme.color.gray[600]};
+ display: flex;
+ padding: 0.75rem 1.75rem;
+ justify-content: center;
+ align-items: center;
+ gap: 0.625rem;
+ cursor: pointer;
+`;
+
+export const Line = styled.div`
+ background: ${({ theme }) => theme.color.gray[200]};
+`;
+
+export const ApplicantList = styled.div`
+ display: flex;
+ width: 600px;
+ flex-direction: column;
+ gap: 28px;
+`;
+
+export const ApplicantContainer = styled.div`
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+`;
+
+export const ProfileText = styled.div`
+ display: flex;
+ gap: 8px;
+`;
+
+export const Name = styled.span`
+ ${({ theme }) => theme.fontStyle.m2.semi};
+ color: ${({ theme }) => theme.color.black};
+`;
+
+export const Data = styled.div`
+ display: flex;
+ align-items: center;
+ gap: 0.25rem;
+`;
+
+export const DataText = styled.span`
+ ${({ theme }) => theme.fontStyle.label};
+ color: ${({ theme }) => theme.color.gray[500]};
+`;
+
+export const Dot = styled.div`
+ width: 0.25rem;
+ height: 0.25rem;
+ border-radius: 0.125rem;
+ background-color: #b4b5b7;
+`;
+
+export const OutButton = styled.div`
+ display: flex;
+ padding: 8px 12px;
+ justify-content: center;
+ align-items: center;
+ gap: 10px;
+ border-radius: 8px;
+ background: ${({ theme }) => theme.color.system};
+ color: ${({ theme }) => theme.color.white};
+`;
diff --git a/src/components/My/PostList/PostCard/TagList/TagItem/index.tsx b/src/components/My/PostList/PostCard/TagList/TagItem/index.tsx
new file mode 100644
index 0000000..dd77ba1
--- /dev/null
+++ b/src/components/My/PostList/PostCard/TagList/TagItem/index.tsx
@@ -0,0 +1,21 @@
+import React from 'react';
+import * as S from './style';
+import { tagType } from 'types/Card';
+
+const TagItem = ({ tag }: { tag: tagType }) => {
+ const text = {
+ WALK: '산책',
+ WORRY: '고민',
+ CHAT: '잡담',
+ EXERCISE: '운동',
+ STUDY: '공부',
+ GO_OUT: '외출',
+ };
+ return (
+
+ #{text[tag]}
+
+ );
+};
+
+export default TagItem;
diff --git a/src/components/My/PostList/PostCard/TagList/TagItem/style.ts b/src/components/My/PostList/PostCard/TagList/TagItem/style.ts
new file mode 100644
index 0000000..4330a1a
--- /dev/null
+++ b/src/components/My/PostList/PostCard/TagList/TagItem/style.ts
@@ -0,0 +1,15 @@
+import styled from '@emotion/styled';
+
+export const Container = styled.div`
+ border: 1px solid #eff0f2;
+ border-radius: 8px;
+ display: flex;
+ padding: 4px 12px;
+ justify-content: center;
+ align-items: center;
+ gap: 10px;
+`;
+
+export const Tag = styled.div`
+ color: #a5a6a9;
+`;
diff --git a/src/components/My/PostList/PostCard/TagList/index.tsx b/src/components/My/PostList/PostCard/TagList/index.tsx
new file mode 100644
index 0000000..9a17486
--- /dev/null
+++ b/src/components/My/PostList/PostCard/TagList/index.tsx
@@ -0,0 +1,16 @@
+import React from 'react';
+import * as S from './style';
+import TagItem from './TagItem';
+import Card from 'types/Card';
+
+const TagList = ({ tag }: Pick) => {
+ return (
+
+ {tag.map((item, index) => (
+
+ ))}
+
+ );
+};
+
+export default TagList;
diff --git a/src/components/My/PostList/PostCard/TagList/style.ts b/src/components/My/PostList/PostCard/TagList/style.ts
new file mode 100644
index 0000000..92be720
--- /dev/null
+++ b/src/components/My/PostList/PostCard/TagList/style.ts
@@ -0,0 +1,6 @@
+import styled from '@emotion/styled';
+
+export const Container = styled.div`
+ display: flex;
+ gap: 12px;
+`;
diff --git a/src/components/My/PostList/PostCard/index.tsx b/src/components/My/PostList/PostCard/index.tsx
new file mode 100644
index 0000000..50012f3
--- /dev/null
+++ b/src/components/My/PostList/PostCard/index.tsx
@@ -0,0 +1,49 @@
+import React from 'react';
+import * as S from './style';
+import TagList from './TagList';
+import MateList from 'components/MateList';
+import Card from 'types/Card';
+
+const PostCard = ({
+ author,
+ author_gender,
+ author_grade,
+ author_school,
+ gender,
+ grade,
+ tag,
+ title,
+}: Card) => {
+ const text: { [key: string]: string } = {
+ ONE: '1학년',
+ TWO: '2학년',
+ THREE: '3학년',
+ FOUR: '4학년',
+ FIVE: '5학년',
+ SIX: '6학년',
+ MALE: '남자',
+ FEMALE: '여자',
+ ANY: '성별무관',
+ };
+
+ return (
+
+
+
+ {author}
+
+
+ {author_school}
+
+ {text[author_grade]}
+
+ {text[author_gender]}
+
+
+ {title}
+
+
+ );
+};
+
+export default PostCard;
diff --git a/src/components/My/PostList/PostCard/style.ts b/src/components/My/PostList/PostCard/style.ts
new file mode 100644
index 0000000..201e9a8
--- /dev/null
+++ b/src/components/My/PostList/PostCard/style.ts
@@ -0,0 +1,52 @@
+import styled from '@emotion/styled';
+
+export const Container = styled.div`
+ width: 550px;
+ padding: 1.25rem 1.5rem;
+ border-radius: 0.5rem;
+ border: 1px solid #f5f6f8;
+ display: flex;
+ flex-direction: column;
+ gap: 1rem;
+ background-color: white;
+`;
+
+export const AuthorDataBox = styled.div`
+ display: flex;
+ align-items: center;
+ gap: 0.5rem;
+`;
+
+export const Author = styled.div`
+ ${({ theme }) => theme.fontStyle.m3.reg}
+ color: ${({ theme }) => theme.color.gray[600]};
+`;
+
+export const Contour = styled.div`
+ width: 0.0625rem;
+ height: 1.25rem;
+ border-radius: 0.3125rem;
+ background: #d9d9d9;
+`;
+
+export const AuthorData = styled.div`
+ display: flex;
+ align-items: center;
+ gap: 0.25rem;
+ span {
+ ${({ theme }) => theme.fontStyle.m3.reg}
+ color: ${({ theme }) => theme.color.gray[400]};
+ }
+`;
+
+export const Dot = styled.div`
+ width: 4px;
+ height: 4px;
+ border-radius: 2px;
+ background-color: ${({ theme }) => theme.color.gray[400]};
+`;
+
+export const Title = styled.div`
+ ${({ theme }) => theme.fontStyle.m1.semi}
+ color: ${({ theme }) => theme.color.black};
+`;
diff --git a/src/components/My/PostList/PostHeader/index.tsx b/src/components/My/PostList/PostHeader/index.tsx
new file mode 100644
index 0000000..8a57250
--- /dev/null
+++ b/src/components/My/PostList/PostHeader/index.tsx
@@ -0,0 +1,13 @@
+import React from 'react';
+import * as S from './style';
+
+const PostHeader = () => {
+ return (
+
+ 내가 작성한 글
+ 신청한 예약
+
+ );
+};
+
+export default PostHeader;
diff --git a/src/components/My/PostList/PostHeader/style.ts b/src/components/My/PostList/PostHeader/style.ts
new file mode 100644
index 0000000..55f44e8
--- /dev/null
+++ b/src/components/My/PostList/PostHeader/style.ts
@@ -0,0 +1,17 @@
+import styled from '@emotion/styled';
+
+export const Wrapper = styled.div`
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ align-self: flex-start;
+ gap: 20px;
+`;
+
+export const Text = styled.div<{ selected: boolean }>`
+ ${({ theme }) => theme.fontStyle.m3.semi};
+ color: ${({ selected, theme }) =>
+ selected ? theme.color.main : theme.color.black};
+ border-bottom: ${({ selected, theme }) =>
+ selected ? `1px solid ${theme.color.main} ` : '0'};
+`;
diff --git a/src/components/My/PostList/index.tsx b/src/components/My/PostList/index.tsx
new file mode 100644
index 0000000..6e9d0d4
--- /dev/null
+++ b/src/components/My/PostList/index.tsx
@@ -0,0 +1,35 @@
+import React from 'react';
+import * as S from './style';
+import PostHeader from './PostHeader';
+import PostCard from './PostCard';
+import { useNavigate } from 'react-router-dom';
+
+const PostList = () => {
+ const navigate = useNavigate();
+
+ return (
+
+
+
+ {[...Array(8)].map((_, idx) => (
+
+ ))}
+
+
+ );
+};
+
+export default PostList;
diff --git a/src/components/My/PostList/style.ts b/src/components/My/PostList/style.ts
new file mode 100644
index 0000000..4a264fa
--- /dev/null
+++ b/src/components/My/PostList/style.ts
@@ -0,0 +1,15 @@
+import styled from '@emotion/styled';
+
+export const Wrapper = styled.div`
+ width: 600px;
+ display: inline-flex;
+ flex-direction: column;
+ gap: 20px;
+`;
+
+export const List = styled.div`
+ width: 600px;
+ display: flex;
+ flex-direction: column;
+ gap: 16px;
+`;
diff --git a/src/components/My/Profile/Detail/index.tsx b/src/components/My/Profile/Detail/index.tsx
new file mode 100644
index 0000000..a021d4f
--- /dev/null
+++ b/src/components/My/Profile/Detail/index.tsx
@@ -0,0 +1,39 @@
+import React, { useState } from 'react';
+import * as S from './style';
+import KebabIcon from 'svg/KebabIcon';
+import Portal from 'components/Portal';
+import ImageChange from 'components/Modal/ImageChange';
+
+const Detail = () => {
+ const [modal, setModal] = useState(false);
+ const [change, setChange] = useState(false);
+
+ return (
+ <>
+
+ setModal(!modal)}>
+
+
+ {modal && (
+
+ {
+ setChange(true);
+ console.log(change);
+ }}>
+ 프로필 변경
+
+ 로그아웃
+
+ )}
+
+ {change && (
+
+ setChange(false)} />
+
+ )}
+ >
+ );
+};
+
+export default Detail;
diff --git a/src/components/My/Profile/Detail/style.ts b/src/components/My/Profile/Detail/style.ts
new file mode 100644
index 0000000..5d039d7
--- /dev/null
+++ b/src/components/My/Profile/Detail/style.ts
@@ -0,0 +1,30 @@
+import styled from '@emotion/styled';
+
+export const Wrapper = styled.div`
+ position: relative;
+`;
+
+export const Button = styled.div``;
+
+export const DetailModal = styled.div`
+ position: absolute;
+ left: -118px;
+ display: inline-flex;
+ padding: 24px;
+ flex-direction: column;
+ align-items: flex-start;
+ gap: 32px;
+ border-radius: 8px;
+ background: ${({ theme }) => theme.color.white};
+ box-shadow: 0px 0px 20px 0px rgba(0, 0, 0, 0.08);
+`;
+
+export const Text = styled.div`
+ ${({ theme }) => theme.fontStyle.m3.reg}
+ color: ${({ theme }) => theme.color.black};
+ cursor: pointer;
+`;
+
+export const WarningText = styled(Text)`
+ color: ${({ theme }) => theme.color.system};
+`;
diff --git a/src/components/My/Profile/UserData/index.tsx b/src/components/My/Profile/UserData/index.tsx
new file mode 100644
index 0000000..eef489c
--- /dev/null
+++ b/src/components/My/Profile/UserData/index.tsx
@@ -0,0 +1,22 @@
+import React from 'react';
+import * as S from './style';
+
+const UserData = () => {
+ return (
+
+
+
+ 한재형
+
+ 광주소프트웨어마이스터고등학교
+
+ 1학년
+
+ 여자
+
+
+
+ );
+};
+
+export default UserData;
diff --git a/src/components/My/Profile/UserData/style.ts b/src/components/My/Profile/UserData/style.ts
new file mode 100644
index 0000000..bcbdd96
--- /dev/null
+++ b/src/components/My/Profile/UserData/style.ts
@@ -0,0 +1,43 @@
+import styled from '@emotion/styled';
+
+export const Wrapper = styled.div`
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ gap: 12px;
+`;
+
+export const Profile = styled.img`
+ width: 3rem;
+ height: 3rem;
+ border-radius: 100%;
+`;
+
+export const Text = styled.div`
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+`;
+
+export const Name = styled.span`
+ ${({ theme }) => theme.fontStyle.m3};
+ color: ${({ theme }) => theme.color.black};
+`;
+
+export const Data = styled.div`
+ display: flex;
+ align-items: center;
+ gap: 0.25rem;
+`;
+
+export const DataText = styled.span`
+ ${({ theme }) => theme.fontStyle.label};
+ color: ${({ theme }) => theme.color.gray[500]};
+`;
+
+export const Dot = styled.div`
+ width: 0.25rem;
+ height: 0.25rem;
+ border-radius: 0.125rem;
+ background-color: #b4b5b7;
+`;
diff --git a/src/components/My/Profile/index.tsx b/src/components/My/Profile/index.tsx
new file mode 100644
index 0000000..8c9be12
--- /dev/null
+++ b/src/components/My/Profile/index.tsx
@@ -0,0 +1,15 @@
+import React from 'react';
+import * as S from './style';
+import UserData from './UserData';
+import Detail from './Detail';
+
+const Profile = () => {
+ return (
+
+
+
+
+ );
+};
+
+export default Profile;
diff --git a/src/components/My/Profile/style.ts b/src/components/My/Profile/style.ts
new file mode 100644
index 0000000..96f0a5e
--- /dev/null
+++ b/src/components/My/Profile/style.ts
@@ -0,0 +1,8 @@
+import styled from '@emotion/styled';
+
+export const Postioner = styled.div`
+ width: 600px;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+`;
diff --git a/src/components/Portal/index.tsx b/src/components/Portal/index.tsx
index 24bc186..d89f298 100644
--- a/src/components/Portal/index.tsx
+++ b/src/components/Portal/index.tsx
@@ -10,10 +10,9 @@ import * as S from './style';
interface Props {
children: ReactElement;
- onClose?: () => void;
}
-const Portal = ({ children, onClose }: Props) => {
+const Portal = ({ children }: Props) => {
const [mounted, setMounted] = useState(false);
const portal = document.getElementById('modal');
@@ -31,9 +30,7 @@ const Portal = ({ children, onClose }: Props) => {
return mounted ? (
ReactDOM.createPortal(
-
- {cloneElement(children, { onClick })}
- ,
+ {cloneElement(children, { onClick })},
portal,
)
) : (
diff --git a/src/pages/home/index.tsx b/src/pages/home/index.tsx
index 24baa89..a16f319 100644
--- a/src/pages/home/index.tsx
+++ b/src/pages/home/index.tsx
@@ -1,7 +1,11 @@
import React, { useState } from 'react';
-import { PostList, Filter, Location, Header, Banner } from 'components';
-import { FilterIcon } from 'svg';
+import PostList from 'components/Post/PostList';
+import { Filter } from 'components/Filter';
import * as S from './style';
+import Location from 'components/Location';
+import Header from 'components/Header';
+import Banner from 'components/Banner';
+import { FilterIcon } from 'svg/index';
const Home = () => {
const [modal, setModal] = useState(false);
@@ -12,17 +16,19 @@ const Home = () => {
-
-
-
- setModal(true)}>
-
- 필터
-
- {modal && setModal(false)} />}
-
-
-
+
+
+
+
+ setModal(true)}>
+
+ 필터
+
+ {modal && setModal(false)} />}
+
+
+
+
>
diff --git a/src/pages/my/cancle/index.tsx b/src/pages/my/cancle/index.tsx
new file mode 100644
index 0000000..fc7d40c
--- /dev/null
+++ b/src/pages/my/cancle/index.tsx
@@ -0,0 +1,17 @@
+import React from 'react';
+import * as S from './style';
+import Header from 'components/Header';
+import CanclePage from 'components/My/CanclePage';
+
+const Cancle = () => {
+ return (
+
+
+
+
+
+
+ );
+};
+
+export default Cancle;
diff --git a/src/pages/my/cancle/style.ts b/src/pages/my/cancle/style.ts
new file mode 100644
index 0000000..9f6fa33
--- /dev/null
+++ b/src/pages/my/cancle/style.ts
@@ -0,0 +1,14 @@
+import styled from '@emotion/styled';
+
+export const Postioner = styled.div`
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+`;
+
+export const Wrapper = styled.div`
+ padding-bottom: 57px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+`;
diff --git a/src/pages/my/edit/index.tsx b/src/pages/my/edit/index.tsx
new file mode 100644
index 0000000..db1ba17
--- /dev/null
+++ b/src/pages/my/edit/index.tsx
@@ -0,0 +1,17 @@
+import DetailPost from 'components/My/DetailPost';
+import React from 'react';
+import * as S from './style';
+import Header from 'components/Header';
+
+const Edit = () => {
+ return (
+
+
+
+
+
+
+ );
+};
+
+export default Edit;
diff --git a/src/pages/my/edit/style.ts b/src/pages/my/edit/style.ts
new file mode 100644
index 0000000..9f6fa33
--- /dev/null
+++ b/src/pages/my/edit/style.ts
@@ -0,0 +1,14 @@
+import styled from '@emotion/styled';
+
+export const Postioner = styled.div`
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+`;
+
+export const Wrapper = styled.div`
+ padding-bottom: 57px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+`;
diff --git a/src/pages/my/index.tsx b/src/pages/my/index.tsx
new file mode 100644
index 0000000..c2cacc6
--- /dev/null
+++ b/src/pages/my/index.tsx
@@ -0,0 +1,19 @@
+import Profile from 'components/My/Profile';
+import React from 'react';
+import * as S from './style';
+import Header from 'components/Header';
+import PostList from 'components/My/PostList';
+
+const My = () => {
+ return (
+
+
+
+
+
+
+
+ );
+};
+
+export default My;
diff --git a/src/pages/my/style.ts b/src/pages/my/style.ts
new file mode 100644
index 0000000..61251b1
--- /dev/null
+++ b/src/pages/my/style.ts
@@ -0,0 +1,15 @@
+import styled from '@emotion/styled';
+
+export const Postioner = styled.div`
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 40px;
+`;
+
+export const Wrapper = styled.div`
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 28px;
+`;
diff --git a/src/svg/ChangeIcon.tsx b/src/svg/ChangeIcon.tsx
new file mode 100644
index 0000000..cf0fbd5
--- /dev/null
+++ b/src/svg/ChangeIcon.tsx
@@ -0,0 +1,37 @@
+import React from 'react';
+
+const ChangeIcon = () => {
+ return (
+
+ );
+};
+
+export default ChangeIcon;
diff --git a/src/svg/KebabIcon.tsx b/src/svg/KebabIcon.tsx
new file mode 100644
index 0000000..d95c584
--- /dev/null
+++ b/src/svg/KebabIcon.tsx
@@ -0,0 +1,18 @@
+import React from 'react';
+
+const KebabIcon = () => {
+ return (
+
+ );
+};
+
+export default KebabIcon;