Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
…coko-Front into feature/#79/Section_Part
  • Loading branch information
bluetree7878 committed Dec 12, 2024
2 parents 3cf4d03 + 0f630aa commit 72ceb7a
Show file tree
Hide file tree
Showing 31 changed files with 1,202 additions and 87 deletions.
2 changes: 1 addition & 1 deletion .github/issue-branch.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ defaultBranch: 'develop'
autoCloseIssue: true
commentMessage: |
git fetch origin
git checkout ${branchName}
git switch ${branchName}
branches:
- label: 🌏 Deploy
Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/ci-cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -76,5 +76,8 @@ jobs:
# Docker Compose로 서비스 배포
- name: Docker run
run: |
if [ -n "$(docker images -f "dangling=true" -q)" ]; then
docker rmi $(docker images -f "dangling=true" -q)
fi
docker compose -f /home/ubuntu/docker-compose.yml down
docker compose -f /home/ubuntu/docker-compose.yml up -d --pull always
23 changes: 0 additions & 23 deletions src/apis/axios/intercepter.ts

This file was deleted.

26 changes: 26 additions & 0 deletions src/apis/axios/interceptor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import api from './instance';
import { getCookie } from '@utils/cookies';

// 요청 인터셉터
api.interceptors.request.use(config => {
// 쿠키에서 accessToken 가져오기
const accessToken: string | undefined = getCookie('accessToken');
if (accessToken) {
config.headers.Authorization = `Bearer ${accessToken}`;
}

return config;
});

// 응답 인터셉터
api.interceptors.response.use(
response => {
// HTTP 상태 코드가 200번대인 경우
console.log(response);
return response;
},
error => {
// HTTP 상태 코드가 에러인 경우
return Promise.reject(error);
}
);
71 changes: 60 additions & 11 deletions src/common/layout/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,37 @@
import { useRef } from 'react';
import { useNavigate } from 'react-router-dom';
import { getImageUrl } from '@utils/getImageUrl';
import HeaderItem from '../ui/HeaderItem';
import { HeaderBox } from './style';
import * as S from '../ui/style';
import HeaderItem from '../ui/HeaderItem';
import Login from '@features/login/ui/Login';
import { ProfileWrapper, ProfileIcon, HeaderIcon } from '../ui/style';
import handleLogout from '@features/login/service/handleLogout';
import isLoggedIn from '@utils/isLoggedIn';
import useModal from '@hooks/useModal';
import useUserStore from '@/store/useUserStore';
import useUserStore from '@store/useUserStore';
import usePopover from '@hooks/usePopover';

export default function Header() {
const points: number = 2999999999;
const lifePoints: number = 5;

const navigate = useNavigate();
const { isShow, openModal, closeModal, Modal } = useModal();
const { user } = useUserStore();

const profileRef = useRef<HTMLDivElement>(null);
const { isOpen, togglePopover, popoverRef } = usePopover({
excludeRefs: [profileRef],
});

const handleProfileClick = () => {
if (isLoggedIn()) {
togglePopover(); // 팝오버 열기/닫기
} else {
openModal(); // 로그인 모달 열기
}
};

return (
<HeaderBox>
{user && (
Expand All @@ -27,14 +48,42 @@ export default function Header() {
/>
</>
)}
<ProfileWrapper onClick={openModal}>
<ProfileIcon src={getImageUrl('테두리.svg')} alt="프로필 테두리" />
<HeaderIcon src={getImageUrl('코코-프로필.svg')} alt="코코 프로필" />
</ProfileWrapper>
{/* Modal 컴포넌트 */}
<Modal isShow={isShow}>
<Login openModal={openModal} closeModal={closeModal} />
</Modal>
<S.ProfileWrapper ref={profileRef} onClick={handleProfileClick}>
<S.ProfileIcon src={getImageUrl('테두리.svg')} alt="프로필 테두리" />
<S.HeaderIcon src={getImageUrl('코코-프로필.svg')} alt="코코 프로필" />
{isLoggedIn() && isOpen && (
<S.ProfilePopover ref={popoverRef} onClick={e => e.stopPropagation()}>
<S.UserNameText>유저이름</S.UserNameText>
<S.UserJoinDate>2024.11.19</S.UserJoinDate>
<S.UserInfoButton
$backgroundColor="#00FAFF"
$boxShadow="0 2px #00E1EC"
onClick={() => navigate('/profile')}
>
프로필
</S.UserInfoButton>
<S.UserInfoButton
$backgroundColor="#3DFF4A"
$boxShadow="0 2px #00EB6A"
onClick={() => navigate('/setting')}
>
설정
</S.UserInfoButton>
<S.UserInfoButton
$backgroundColor="#FF3F3D"
$boxShadow="0 2px #EB0000"
onClick={handleLogout}
>
로그아웃
</S.UserInfoButton>
</S.ProfilePopover>
)}
</S.ProfileWrapper>
{!isLoggedIn() && (
<Modal isShow={isShow}>
<Login openModal={openModal} closeModal={closeModal} />
</Modal>
)}
</HeaderBox>
);
}
2 changes: 2 additions & 0 deletions src/common/layout/style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export const HeaderBox = styled.header`
height: 42px;
position: fixed;
padding-right: 20px;
z-index: 1;
`;

export const LogoBoxWrapper = styled.div`
Expand All @@ -42,4 +43,5 @@ export const OverRay = styled.div`
width: 100vw;
height: 100vh;
background-color: rgba(0, 0, 0, 0.2);
z-index: 100;
`;
92 changes: 73 additions & 19 deletions src/common/ui/style.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,12 @@
import styled from 'styled-components';
import styled, { keyframes } from 'styled-components';
import { Link } from 'react-router-dom';

interface SectionButtonProps {
$backgroundImage: string;
interface UserInfoButtonProps {
$backgroundColor: string;
$boxShadow: string;
}

interface MenuButtonProps {
$activeStyle: boolean;
}

interface IconWrapperProps {
$color: string;
}

export const SectionButton = styled.button<SectionButtonProps>`
export const SectionButton = styled.button<{ $backgroundImage: string }>`
width: 100px;
height: 75px;
margin-top: 75px;
Expand All @@ -31,7 +24,7 @@ export const MenuButtonWrapper = styled.nav`
display: inline-block;
`;

export const MenuButton = styled.button<MenuButtonProps>`
export const MenuButton = styled.button<{ $activeStyle: boolean }>`
width: 193px;
height: 42px;
font-size: 15px;
Expand All @@ -58,7 +51,7 @@ export const MenuIcon = styled.img`
height: 26px;
`;

export const IconWrapper = styled.div<IconWrapperProps>`
export const IconWrapper = styled.div<{ $color: string }>`
display: flex;
align-items: center;
margin-right: 16px;
Expand All @@ -69,11 +62,6 @@ export const IconWrapper = styled.div<IconWrapperProps>`
color: ${({ $color }) => $color};
`;

export const ProfileWrapper = styled.div`
position: relative;
cursor: pointer;
`;

export const ProfileIcon = styled.img`
position: absolute;
width: 30px;
Expand All @@ -90,3 +78,69 @@ export const LogoImg = styled.img`
width: 147px;
height: 117px;
`;

export const ProfileWrapper = styled.div`
position: relative;
cursor: pointer;
`;

// Popover 열릴 때 애니메이션
const slideIn = keyframes`
from {
opacity: 0;
transform: translateY(10px);
}
to {
opacity: 1;
transform: translateY(0);
}
`;

export const ProfilePopover = styled.div`
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
position: absolute;
margin-top: 3px;
right: 0;
cursor: default;
width: 200px;
height: 200px;
background-color: #fff;
border-radius: 15px;
border: 3px solid #ffb53d;
animation: ${slideIn} 0.3s ease-out;
`;

export const UserNameText = styled.p`
color: #000;
font-size: 18px;
text-align: center;
font-weight: 700;
`;

export const UserJoinDate = styled.p`
font-weight: 300;
color: #cbcbcb;
font-size: 12px;
`;

export const UserInfoButton = styled.button<UserInfoButtonProps>`
width: 80%;
height: 30px;
margin-top: 12px;
border: none;
background-color: ${({ $backgroundColor }) => $backgroundColor};
box-shadow: ${({ $boxShadow }) => $boxShadow};
text-align: center;
font-size: 17px;
font-weight: 700;
color: #ffffff;
border-radius: 6px;
text-shadow: -1px 0 #000, 0 1px #000, 1px 0 #000, 0 -1px #000;
&:hover {
transform: scale(1.05);
transition: transform 0.2s ease;
}
`;
23 changes: 23 additions & 0 deletions src/features/login/service/handleLogin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// import { setCookie } from '@utils/cookies';

const BASE_URL = import.meta.env.VITE_BASE_URL;

const handleLogin = (provider: 'google' | 'kakao' | 'github') => {
const redirectUrl = `${BASE_URL}/auth/${provider}`;
window.location.href = redirectUrl;

// 테스트용 accessToken 및 refreshToken 생성 및 쿠키에 저장 (실제 Service에 배포할 때는 주석 달거나 삭제)
// const fakeAccessToken = 'test.access.token';
// const fakeRefreshToken = 'test.refresh.token';

// setCookie('accessToken', fakeAccessToken, { path: '/', maxAge: 3600 }); // 1시간 유효
// setCookie('refreshToken', fakeRefreshToken, {
// path: '/',
// maxAge: 3600 * 24 * 30,
// }); // 30일 유효

// alert('AccessToken 생성 완료: ' + fakeAccessToken);
// alert('RefreshToken 생성 완료: ' + fakeRefreshToken);
};

export default handleLogin;
9 changes: 9 additions & 0 deletions src/features/login/service/handleLogout.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { removeCookie } from '@utils/cookies';

const handleLogout = () => {
removeCookie('accessToken');
removeCookie('refreshToken');
window.location.href = '/';
};

export default handleLogout;
8 changes: 0 additions & 8 deletions src/features/login/service/handleSocialLogin.ts

This file was deleted.

1 change: 0 additions & 1 deletion src/features/login/styles.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import styled, { keyframes } from 'styled-components';
import { getImageUrl } from './../../utils/getImageUrl';

interface SocialLoginLinkProps {
$color: string;
Expand Down
8 changes: 4 additions & 4 deletions src/features/login/ui/Login.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
DashLineHr,
} from '../styles';
import { LogoImg } from '@common/ui/style';
import handleSocialLogin from '../service/handleSocialLogin';
import handleLogin from '../service/handleLogin';

interface LoginProps {
openModal: () => void;
Expand All @@ -28,23 +28,23 @@ export default function Login({ closeModal }: LoginProps) {
<SocialLoginButton
$color="#000000"
$backgroundColor="#ffffff"
onClick={() => handleSocialLogin('google')}
onClick={() => handleLogin('google')}
>
<img src={getImageUrl('구글.svg')} alt="구글 로그인" />
Google 로그인
</SocialLoginButton>
<SocialLoginButton
$color="#000000"
$backgroundColor="#FEE500"
onClick={() => handleSocialLogin('kakao')}
onClick={() => handleLogin('kakao')}
>
<img src={getImageUrl('카카오.svg')} alt="카카오 로그인" />
Kakao 로그인
</SocialLoginButton>
<SocialLoginButton
$color="#ffffff"
$backgroundColor="#000000"
onClick={() => handleSocialLogin('github')}
onClick={() => handleLogin('github')}
>
<img src={getImageUrl('깃허브.svg')} alt="깃허브 로그인" />
GitHub 로그인
Expand Down
Loading

0 comments on commit 72ceb7a

Please sign in to comment.