Skip to content

Commit

Permalink
Merge pull request #74 from pobu-team/develop
Browse files Browse the repository at this point in the history
Develop -> Main
  • Loading branch information
himyne authored Jan 29, 2024
2 parents 747de93 + 1cd88b1 commit baf7919
Show file tree
Hide file tree
Showing 39 changed files with 1,407 additions and 222 deletions.
9 changes: 1 addition & 8 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,8 @@ module.exports = {
'object-curly-spacing': ['error', 'always'],
'key-spacing': ['error', { mode: 'strict' }],
'arrow-spacing': ['error', { before: true, after: true }],
'import/no-extraneous-dependencies': ['error', {
devDependencies: [
'**/*.test.js',
'**/*.test.jsx',
'**/*.test.ts',
'**/*.test.tsx',
],
}],
'react/require-default-props': 'off',
'max-len': ['error', { code: 150 }],
'import/extensions': ['error', 'ignorePackages', {
js: 'never',
jsx: 'never',
Expand Down
685 changes: 649 additions & 36 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,13 @@
},
"dependencies": {
"@tanstack/react-query": "^5.7.0",
"@types/navermaps": "^3.7.3",
"axios": "^1.4.0",
"framer-motion": "^10.16.4",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-ga4": "^2.1.0",
"react-naver-maps": "^0.1.3",
"react-router": "^6.9.0",
"react-router-dom": "^6.9.0",
"recoil": "^0.7.7",
Expand Down
4 changes: 2 additions & 2 deletions src/components/footer/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import styled from 'styled-components';

import { useReadLocalStorage } from 'usehooks-ts';

const ButtonContainer = styled.div<{ active: boolean}>`
const ButtonContainer = styled.div<{ active?: boolean}>`
width: 100%;
height: 7rem;
margin-bottom: .3rem;
Expand Down Expand Up @@ -35,7 +35,7 @@ export default function Button({
text: string;
imgSrc: string;
onClickFunc: () =>void;
active: boolean;
active?: boolean;
}) {
const isDarkMode = useReadLocalStorage('darkMode');

Expand Down
4 changes: 1 addition & 3 deletions src/components/footer/NavigationBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,21 +38,19 @@ export default function NavigationBar() {
/>
<Button
text="매장찾기"
imgSrc="shop_search"
imgSrc={searchActive ? 'shop_search_active' : 'shop_search_disable'}
onClickFunc={() => handleNavClick('/search', 'GNB Search')}
active={searchActive}
/>
<Button
text="포즈추천"
imgSrc="recommend"
onClickFunc={() => handleNavClick('/people', 'GNB Home')}
active={searchActive}
/>
<Button
text="포즈등록"
imgSrc="register"
onClickFunc={() => handleNavClick('/register', 'GNB Home')}
active={searchActive}
/>
<Button
text="마이"
Expand Down
13 changes: 1 addition & 12 deletions src/components/layout/MyPageLayout.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import { Outlet, useLocation } from 'react-router-dom';
import { Outlet } from 'react-router-dom';
import styled from 'styled-components';
import NavigationBar from '../footer/NavigationBar';
import TitleHeader from '../header/TitleHeader';
import FloatingHeader from '../../ui/FloatingHeader';

const Container = styled.div`
width: 100%;
Expand All @@ -14,17 +12,8 @@ const Container = styled.div`
`;

export default function MyPageLayout() {
const { pathname } = useLocation();
const Titles: Record<string, string> = {
'/mylike': '찜한 포즈',
'/upload': '업로드한 포즈',
};

return (
<Container>
<FloatingHeader>
<TitleHeader title={pathname === '/mypage' ? '마이페이지' : Titles[pathname]} />
</FloatingHeader>
<main>
<Outlet />
</main>
Expand Down
29 changes: 29 additions & 0 deletions src/components/layout/SearchLayout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { Outlet } from 'react-router-dom';
import styled from 'styled-components';
// eslint-disable-next-line import/no-extraneous-dependencies
import { NavermapsProvider } from 'react-naver-maps';
import NavigationBar from '../footer/NavigationBar';

const Container = styled.div`
width: 100%;
max-width: 375px;
margin: auto;
min-height: 100vh;
max-height: fit-content;
background-color: ${(props) => props.theme.colors.mainBackground};
`;

export default function SearchLayout() {
return (
<NavermapsProvider
ncpClientId={process.env.REACT_APP_NAVER_CLIENT_ID as string}
>
<Container>
<main>
<Outlet />
</main>
<NavigationBar />
</Container>
</NavermapsProvider>
);
}
28 changes: 22 additions & 6 deletions src/components/main/Heading.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { useRecoilValue } from 'recoil';
import styled from 'styled-components';
import {
animate, easeInOut, motion, useMotionValue, useTransform,
} from 'framer-motion';
import { useEffect } from 'react';
import CountSelector from '../../recoil/countState';

const HeadingContainer = styled.div`
Expand All @@ -19,8 +23,21 @@ const HeadingContainer = styled.div`
}
`;

const Number = styled(motion.div)`
text-decoration: underline;
display: inline;
`;

export default function Heading() {
const count = useRecoilValue(CountSelector);
const poseCount = useRecoilValue(CountSelector);

const count = useMotionValue(0);
const rounded = useTransform(count, (latest) => Math.round(latest));

useEffect(() => {
const controls = animate(count, poseCount, { duration: 1.5 });
return controls.stop;
}, []);

return (
<HeadingContainer>
Expand All @@ -30,11 +47,10 @@ export default function Heading() {
{' '}
포즈가
{' '}
<span style={{ textDecoration: 'underline' }}>
{count}
</span>
이 있어요!
<Number style={{ textDecoration: 'underline' }}>
{rounded}
</Number>
장이 있어요!
</h1>
</HeadingContainer>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { useNavigate } from 'react-router';
import { useRecoilValue } from 'recoil';
import { useEffect } from 'react';
import { useLocalStorage } from 'usehooks-ts';
import { kakaoTokenSelector } from '../../../recoil/loginState';
import { kakaoTokenSelector } from '../../recoil/loginState';

export default function KakaoLogIn() {
const navigate = useNavigate();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import { useRecoilValue } from 'recoil';
import styled from 'styled-components';
import { AllPoseSelector, PoseSelector } from '../../../recoil/poseState';
import EmptyPose from '../../common/EmptyPose';
import PoseList from '../../common/PoseList';
import { ALL_PEOPLE_TAG } from '../../../constant/tagId';
import useFetchLikeList from '../../../hooks/useFetchLikeList';
import { useFetchPoses } from '../../../queries/poses';
import { AllPoseSelector, PoseSelector } from '../../recoil/poseState';
import EmptyPose from '../common/EmptyPose';
import PoseList from '../common/PoseList';
import { ALL_PEOPLE_TAG } from '../../constant/tagId';
import useFetchLikeList from '../../hooks/useFetchLikeList';

const Container = styled.div`
padding: ${(props) => props.theme.sizes.contentPadding};
Expand Down
File renamed without changes.
34 changes: 34 additions & 0 deletions src/components/mypage/PoseTab.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import styled from 'styled-components';

const TabButton = styled.button<{active: boolean}>`
width: 50%;
background-color: transparent;
border: none;
font-size: 1.6rem;
line-height: 2.6rem;
font-weight: 600;
color:${(props) => (props.active ? props.theme.colors.text : props.theme.colors.textAlternative)};
padding-block: 1.2rem;
border-bottom: 2px solid ${(props) => (props.active ? props.theme.colors.text : 'transparent')};
cursor: pointer;
`;

interface PoseTabProps {
isShowingRegisteredPoses: boolean,
toggleTab: () => void
}

function PoseTab({ isShowingRegisteredPoses, toggleTab }: PoseTabProps) {
return (
<div>
<TabButton active={isShowingRegisteredPoses} onClick={toggleTab}>
등록한 포즈
</TabButton>
<TabButton active={!isShowingRegisteredPoses} onClick={toggleTab}>
찜한 포즈
</TabButton>
</div>
);
}

export default PoseTab;
31 changes: 31 additions & 0 deletions src/components/mypage/RegisteredPoseList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import styled from 'styled-components';
import useFetchLikeList from '../../hooks/useFetchLikeList';
import useFetchMyPoses from '../../hooks/useFetchMyPoses';
import PoseList from '../common/PoseList';
import EmptyPose from '../common/EmptyPose';

const PoseContainer = styled.div`
padding: ${(props) => props.theme.sizes.contentPadding};
`;

function RegisteredPoseList() {
const likePoseIdArr = useFetchLikeList();
const { isLoading, data: filteredPoses } = useFetchMyPoses();

if (!isLoading && filteredPoses && filteredPoses.length > 0) {
return (
<PoseContainer>
<PoseList
poses={filteredPoses}
likePoseIdArr={likePoseIdArr}
/>
</PoseContainer>
);
}

return (
<EmptyPose text="등록한" />
);
}

export default RegisteredPoseList;
67 changes: 67 additions & 0 deletions src/components/mypage/UserProfile.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import styled from 'styled-components';
import { useNavigate } from 'react-router';
import useFetchMyInfo from '../../hooks/useFetchMemberInfo';

const ProfileContainer = styled.div`
padding: 1.6rem 2.4rem;
display: flex;
justify-content: space-between;
align-items: center;
`;

const ImageNameBox = styled.div`
display: flex;
align-items: center;
img {
width: 64px;
height: 64px;
border-radius: 100%;
margin-right: 1.2rem;
}
p {
font-size: 2rem;
line-height: 2.6rem;
font-weight: 600;
}
`;

const LogoutButton = styled.button`
background-color: ${(props) => props.theme.colors.backgroundSecondary};
padding: 0.6rem 1.2rem;
font-size: 1.4rem;
line-height: 2.4rem;
font-weight: 600;
color: ${(props) => props.theme.colors.textNormal};
border: none;
border-radius: 99px;
width: 7.3rem;
height: 3.6rem;
cursor: pointer;
`;

function UserProfile() {
const { data: myInfoResponse } = useFetchMyInfo();
const navigate = useNavigate();
return (
<ProfileContainer>
<ImageNameBox>
<img src={myInfoResponse?.data.profileImageUrl} alt="profile pic" />
<p>{myInfoResponse?.data.name}</p>
</ImageNameBox>
<LogoutButton
type="button"
onClick={() => {
localStorage.removeItem('accessToken');
navigate('/');
}}
>
로그아웃

</LogoutButton>
</ProfileContainer>
);
}

export default UserProfile;
Loading

0 comments on commit baf7919

Please sign in to comment.