>
diff --git a/src/components/detail/Status.tsx b/src/components/detail/Status.tsx
index 8d2fac8..3da2d90 100644
--- a/src/components/detail/Status.tsx
+++ b/src/components/detail/Status.tsx
@@ -34,22 +34,24 @@ const Status = ({ pokemonState, isLoading }: PokemonInfoExtendsProps) => {
{windowWidth <= 768 && (
<>
-
-
-
-
-
-
-
최종 스탯
-
- {pokemon?.stats.reduce(
- (acc, baseStat) => acc + baseStat.base_stat,
- 0,
- )}
+
+
+
+
+
+
+
+
최종 스탯
+
+ {pokemon?.stats.reduce(
+ (acc, baseStat) => acc + baseStat.base_stat,
+ 0,
+ )}
+
diff --git a/src/components/header/Header.module.scss b/src/components/header/Header.module.scss
index c1a4e2e..8d45122 100644
--- a/src/components/header/Header.module.scss
+++ b/src/components/header/Header.module.scss
@@ -79,6 +79,11 @@
justify-content: center;
border-left: 1px solid #000;
border-bottom: 2px solid #000;
+
+ &__last {
+ border-right: 1px solid #000;
+ cursor: pointer;
+ }
}
.nav__profile__img {
@@ -92,11 +97,6 @@
}
}
-.nav__item:nth-child(4) {
- cursor: pointer;
- border-right: 1px solid #000;
-}
-
.logo {
flex-shrink: 0;
@@ -219,6 +219,7 @@
.nav__item__mobile:nth-child(4) {
border: none;
width: 100vw;
+ cursor: pointer;
}
.active {
diff --git a/src/components/header/Header.tsx b/src/components/header/Header.tsx
index 40184cd..9b534a8 100644
--- a/src/components/header/Header.tsx
+++ b/src/components/header/Header.tsx
@@ -5,14 +5,14 @@ import { FaRegAddressCard } from '@react-icons/all-files/fa/FaRegAddressCard';
import { BsFilePlus } from '@react-icons/all-files/bs/BsFilePlus';
import { RiUserVoiceFill } from '@react-icons/all-files/ri/RiUserVoiceFill';
import { FiLogIn } from '@react-icons/all-files/fi/FiLogIn';
-import { useEffect, useRef, useState } from 'react';
+import { useCallback, useEffect, useRef, useState } from 'react';
import useUserStore from '@/store/useUsersStore';
import SearchInput from '../search/Search';
-import useUserInfoChangeStore from '@/store/useUserInfoChangeStore';
import MobileNav from './MobileNav';
import MobileSearchBox from './MobileSearchBox';
import MobileNavMenu from './MobileNavMenu';
import useCalculateInnerWidth from '@/hook/useCalculateInnerWidth';
+import useUserInfoChangeStore from '@/store/useUserInfoChangeStore';
const Header = () => {
const [isOpen, setIsOpen] = useState(false);
@@ -20,9 +20,9 @@ const Header = () => {
const [navOpen, setNavOpen] = useState(false);
const location = useLocation();
-
- const { user } = useUserStore();
const { imgUrl } = useUserInfoChangeStore();
+ const { user } = useUserStore();
+
const windowWidth = useCalculateInnerWidth();
const dropdownRef = useRef
(null);
@@ -33,14 +33,6 @@ const Header = () => {
setIsOpen(false);
};
- const props = {
- isOpen,
- setIsOpen,
- dropdownRef,
- toggleDropdown,
- onClickOutSide,
- };
-
useEffect(() => {
document.addEventListener('mousedown', onClickOutSide);
return () => {
@@ -72,17 +64,17 @@ const Header = () => {
setNavOpen(false);
}, [location]);
- const onToggleSearchBox = () => {
+ const onToggleSearchBox = useCallback(() => {
setNavOpen(false);
setSearchOpen((prev) => !prev);
- };
+ }, []);
- const onToggleNavMenu = () => {
+ const onToggleNavMenu = useCallback(() => {
setSearchOpen(false);
setNavOpen((prev) => !prev);
- };
+ }, []);
- const onCloseOverlay = () => {
+ const onCloseOverlay = useCallback(() => {
if (searchOpen === true) {
setSearchOpen(false);
}
@@ -90,7 +82,7 @@ const Header = () => {
if (navOpen === true) {
setNavOpen(false);
}
- };
+ }, [searchOpen, navOpen]);
return (
<>
@@ -127,21 +119,27 @@ const Header = () => {
{user ? (
-
-
+
+
+
+
+ 나의 메뉴
) : (
-
+
+
+ 로그인
+
)}
@@ -157,6 +155,7 @@ const Header = () => {
+
{searchOpen && (
@@ -164,7 +163,7 @@ const Header = () => {
)}
{navOpen && (
-
+
)}
>
diff --git a/src/components/header/MobileMenuBtn.tsx b/src/components/header/MobileMenuBtn.tsx
index a8424d0..de2c2b9 100644
--- a/src/components/header/MobileMenuBtn.tsx
+++ b/src/components/header/MobileMenuBtn.tsx
@@ -7,8 +7,6 @@ interface Props extends SVGMotionProps
{
transition?: Transition;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
lineProps?: any;
- width?: number;
- height?: number;
}
const MobileMenuBtn = ({
@@ -50,6 +48,7 @@ const MobileMenuBtn = ({
translateY: -2,
},
};
+
lineProps = {
stroke: color,
strokeWidth: strokeWidth as number,
@@ -57,11 +56,19 @@ const MobileMenuBtn = ({
initial: 'closed',
animate: variant,
transition,
- ...lineProps,
};
const unitHeight = 4;
const unitWidth = (unitHeight * (width as number)) / (height as number);
+ const topLineProps = {
+ ...lineProps,
+ style: { transformOrigin: '2.85714px 0px' },
+ };
+ const bottomLineProps = {
+ ...lineProps,
+ style: { transformOrigin: '2.85714px 4px' },
+ };
+
return (
);
diff --git a/src/components/header/MobileNav.tsx b/src/components/header/MobileNav.tsx
index 69e75e6..48fc8cf 100644
--- a/src/components/header/MobileNav.tsx
+++ b/src/components/header/MobileNav.tsx
@@ -2,6 +2,7 @@ import { useLocation } from 'react-router-dom';
import styles from './Header.module.scss';
import { MobileMenuBtn } from './MobileMenuBtn';
import { IoSearchSharp } from '@react-icons/all-files/io5/IoSearchSharp';
+import useCalculateInnerWidth from '@/hook/useCalculateInnerWidth';
const MobileNav = ({
onToggleSearchBox,
@@ -13,6 +14,7 @@ const MobileNav = ({
navOpen: boolean;
}) => {
const location = useLocation();
+ const windowWidth = useCalculateInnerWidth();
return (
@@ -22,9 +24,11 @@ const MobileNav = ({
)}
-
-
-
+ {windowWidth <= 768 && (
+
+
+
+ )}
);
};
diff --git a/src/components/header/MobileNavMenu.tsx b/src/components/header/MobileNavMenu.tsx
index 858db36..d5f1de1 100644
--- a/src/components/header/MobileNavMenu.tsx
+++ b/src/components/header/MobileNavMenu.tsx
@@ -1,4 +1,4 @@
-import { Dispatch, MutableRefObject, SetStateAction, useEffect } from 'react';
+import { useState } from 'react';
import { NavLink } from 'react-router-dom';
import { FaRegAddressCard } from '@react-icons/all-files/fa/FaRegAddressCard';
import { BsFilePlus } from '@react-icons/all-files/bs/BsFilePlus';
@@ -6,37 +6,22 @@ import { RiUserVoiceFill } from '@react-icons/all-files/ri/RiUserVoiceFill';
import { FiLogIn } from '@react-icons/all-files/fi/FiLogIn';
import styles from './Header.module.scss';
import useUserStore from '@/store/useUsersStore';
+import { Modalportal } from '@/portal';
import SocialLogin from '../users/SocialLogin';
-import useUserInfoChangeStore from '@/store/useUserInfoChangeStore';
+import MobileModal from '../modal/MobileModal';
-interface MobileNavMenu {
- props: {
- isOpen: boolean;
- setIsOpen: Dispatch>;
- dropdownRef: MutableRefObject;
- toggleDropdown: () => void;
- onClickOutSide: (e: MouseEvent) => void;
- };
-}
-
-const MobileNavMenu = ({ props }: MobileNavMenu) => {
- console.log(props);
+const MobileNavMenu = () => {
+ const [isModalOpen, setIsModalOpen] = useState(false);
const { user } = useUserStore();
- const { imgUrl } = useUserInfoChangeStore();
- const { isOpen, setIsOpen, dropdownRef, toggleDropdown, onClickOutSide } =
- props;
-
- useEffect(() => {
- document.addEventListener('mousedown', onClickOutSide);
- return () => {
- document.removeEventListener('mousedown', onClickOutSide);
- };
- }, [imgUrl, onClickOutSide]);
const onClick = (e: React.MouseEvent) => {
e.stopPropagation();
};
+ const onToggleModal = () => {
+ setIsModalOpen((prev) => !prev);
+ };
+
return (
<>
-
+
{user ? (
<>
@@ -84,14 +65,22 @@ const MobileNavMenu = ({ props }: MobileNavMenu) => {
height={31}
/>
+ 나의 메뉴
>
) : (
<>
+ 로그인
>
)}
-
+ {isModalOpen && (
+
+
+
+
+
+ )}
>
diff --git a/src/components/modal/CardModal.module.scss b/src/components/modal/CardModal.module.scss
index c9c821f..826a643 100644
--- a/src/components/modal/CardModal.module.scss
+++ b/src/components/modal/CardModal.module.scss
@@ -12,7 +12,8 @@
position: relative;
width: 100%;
height: 100%;
- background-color: rgba(0, 0, 0, 0.5);
+ background-color: rgba(0, 0, 0, 0.4);
+ backdrop-filter: blur(1.5px);
display: flex;
justify-content: center;
align-items: center;
@@ -27,6 +28,11 @@
width: 428px;
justify-content: center;
align-items: center;
+
+ @media (max-width: 769px) {
+ width: 300px;
+ height: 400px;
+ }
}
}
diff --git a/src/components/modal/MobileModal.tsx b/src/components/modal/MobileModal.tsx
new file mode 100644
index 0000000..b7bbc64
--- /dev/null
+++ b/src/components/modal/MobileModal.tsx
@@ -0,0 +1,15 @@
+import { ReactNode } from 'react';
+
+import styles from '@/components/users/SocialLogin.module.scss';
+
+const MobileSocialLogin = ({ children }: { children: ReactNode }) => {
+ return (
+
+ );
+};
+
+export default MobileSocialLogin;
diff --git a/src/components/mypage/Introduce.tsx b/src/components/mypage/Introduce.tsx
index 7b0b21b..150ff7d 100644
--- a/src/components/mypage/Introduce.tsx
+++ b/src/components/mypage/Introduce.tsx
@@ -14,6 +14,7 @@ import { PROFILE_DEFAULT_IMG, STORAGE_DOWNLOAD_URL } from '@/lib/constants';
import useUserInfoChangeStore from '@/store/useUserInfoChangeStore';
import { getDocument, setDocument } from '@/lib/firebaseQuery';
import { IoIosCloseCircle } from '@react-icons/all-files/io/IoIosCloseCircle';
+import useCalculateInnerWidth from '@/hook/useCalculateInnerWidth';
const Introduce = () => {
const [isLoading, setIsLoading] = useState(false);
@@ -21,6 +22,7 @@ const Introduce = () => {
const [editText, setEditText] = useState('');
const { user } = useUserStore();
const { userName, setUserName, imgUrl, setImgUrl } = useUserInfoChangeStore();
+ const windowWidth = useCalculateInnerWidth();
useEffect(() => {
if (user?.photoURL) {
@@ -152,8 +154,8 @@ const Introduce = () => {
{editMode ? (
<>
@@ -164,7 +166,7 @@ const Introduce = () => {
>
) : (
@@ -222,7 +224,11 @@ const Introduce = () => {
onClick={editMode ? onEditModeOff : onEditModeOn}
disabled={isLoading}
>
-
{editMode ? '저장하기' : '프로필 편집'}
+ {windowWidth <= 768 ? (
+
{editMode ? '저장' : '편집'}
+ ) : (
+
{editMode ? '저장하기' : '프로필 편집'}
+ )}
diff --git a/src/components/mypage/MobileMypageAlert.tsx b/src/components/mypage/MobileMypageAlert.tsx
new file mode 100644
index 0000000..1c678ec
--- /dev/null
+++ b/src/components/mypage/MobileMypageAlert.tsx
@@ -0,0 +1,43 @@
+import styles from '@/components/users/SocialLogin.module.scss';
+import { useNavigate } from 'react-router-dom';
+
+const MobileMypageAlert = ({ isOpen }: { isOpen: boolean }) => {
+ const navigate = useNavigate();
+
+ const onMovetoMakecard = () => {
+ navigate('/cardEdit');
+ };
+ return (
+ <>
+
알림
+
+
+
+
+ 카드 제작 페이지로 이동하시겠어요?
+
+
+
+
+
+ >
+ );
+};
+
+export default MobileMypageAlert;
diff --git a/src/components/mypage/MyLikedPokemon.tsx b/src/components/mypage/MyLikedPokemon.tsx
index 452d60d..de49f8c 100644
--- a/src/components/mypage/MyLikedPokemon.tsx
+++ b/src/components/mypage/MyLikedPokemon.tsx
@@ -7,12 +7,14 @@ import RenderPokemon from './RenderPokemon';
import { updateDocument } from '@/lib/firebaseQuery';
import { Pagination } from 'antd';
import { useState } from 'react';
+import useCalculateInnerWidth from '@/hook/useCalculateInnerWidth';
const MyLikedPokemon = () => {
const { user } = useUserStore();
const { pokemonData } = useLikedStore();
const [currentPage, setCurrentPage] = useState(1);
- const itemsPerPage = 12;
+ const windowWidth = useCalculateInnerWidth();
+ const itemsPerPage = windowWidth <= 768 ? 6 : 12;
const navigate = useNavigate();
diff --git a/src/components/mypage/Mycard.tsx b/src/components/mypage/Mycard.tsx
index 1a349e8..16ed63c 100644
--- a/src/components/mypage/Mycard.tsx
+++ b/src/components/mypage/Mycard.tsx
@@ -2,12 +2,19 @@ import { useNavigate } from 'react-router-dom';
import styles from './Mypage.module.scss';
import { FiPlus } from '@react-icons/all-files/fi/FiPlus';
import { Modalportal } from '@/portal';
-import { useEffect, useState, MouseEvent } from 'react';
+import { useEffect, useState, MouseEvent, useCallback } from 'react';
import CardModal from '../modal/CardModal';
import { deleteDocument, getAllDocument } from '@/lib/firebaseQuery';
import useUserStore from '@/store/useUsersStore';
import { DocumentData } from 'firebase/firestore';
import PokemonCard from '../card/PokemonCard';
+import useCalculateInnerWidth from '@/hook/useCalculateInnerWidth';
+import useSlide from '@/hook/useSlide';
+import { IoChevronForward } from '@react-icons/all-files/io5/IoChevronForward';
+import { IoChevronBack } from '@react-icons/all-files/io5/IoChevronBack';
+import { motion } from 'framer-motion';
+import MobileMypageAlert from './MobileMypageAlert';
+import MobileModal from '../modal/MobileModal';
export interface Card {
id: string;
@@ -16,12 +23,15 @@ export interface Card {
const Mycard = () => {
const [isOpen, setIsOpen] = useState(false);
+ const [isAlert, setIsAlert] = useState(false);
const [cards, setCards] = useState
([]);
const [selectedCard, setSelectedCard] = useState(
null,
);
const navigate = useNavigate();
const { user } = useUserStore();
+ const windowWidth = useCalculateInnerWidth();
+ const { index, prevSlide, nextSlide } = useSlide(6, 1);
useEffect(() => {
const fetchData = async () => {
@@ -40,6 +50,18 @@ const Mycard = () => {
fetchData();
}, [user]);
+ useEffect(() => {
+ if (isOpen) {
+ document.body.style.overflow = 'hidden';
+ } else {
+ document.body.style.overflow = 'auto';
+ }
+
+ return () => {
+ document.body.style.overflow = 'auto';
+ };
+ }, [isOpen]);
+
useEffect(() => {
const handleKeyUp = (event: KeyboardEvent) => {
if (event.key === 'Escape') {
@@ -55,8 +77,16 @@ const Mycard = () => {
};
}, []);
+ useEffect(() => {
+ if (windowWidth > 768) {
+ setIsAlert(false);
+ }
+ }, [windowWidth]);
+
const onMoveMakeCard = () => {
- navigate('/cardEdit');
+ if (windowWidth <= 768) {
+ setIsAlert((prev) => !prev);
+ } else navigate('/cardEdit');
};
const onModalToggle = (card?: Card) => {
@@ -86,16 +116,9 @@ const Mycard = () => {
};
const cardLayout = [];
- const maxCards = 6;
- for (let i = 0; i < maxCards; i++) {
+ for (let i = 0; i < 6; i++) {
if (i < cards.length) {
const card = cards[i];
- const pokemonNickName = {
- pokemonNickName1: card?.data.pokemonCardData[1],
- pokemonNickName2: card?.data.pokemonCardData[2],
- pokemonName: card?.data.pokemonCardData[3],
- };
-
cardLayout.push(
{
+
,
);
}
}
+ console.log(index);
+
+ const onCloseOverlay = useCallback(() => {
+ if (isAlert === true) {
+ setIsAlert(false);
+ }
+ }, [isAlert]);
+
return (
<>
-
내가 만든 포켓몬 카드
+
나의 포켓몬 카드
-
{cardLayout}
+
+ {windowWidth <= 768 ? (
+
+
+
+
+ {cardLayout[index]}
+
+
+
+
+ ) : (
+ cardLayout
+ )}
+
+ {windowWidth <= 768 && (
+
+ {index + 1} / {cardLayout.length}
+
+ )}
+
{isOpen && (
{
/>
)}
+
+ {isAlert && (
+
+
+
+
+
+
+
+ )}
>
);
};
diff --git a/src/components/mypage/Mypage.module.scss b/src/components/mypage/Mypage.module.scss
index 927839d..b4e7cd5 100644
--- a/src/components/mypage/Mypage.module.scss
+++ b/src/components/mypage/Mypage.module.scss
@@ -1,8 +1,20 @@
+.mypage {
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ width: 100%;
+
+ @media (max-width: 769px) {
+ padding: 0 20px;
+ }
+}
+
// Introduce
.intro {
&__container {
- width: 1200px;
+ width: 100%;
height: 222px;
flex-shrink: 0;
border-radius: 10px;
@@ -11,6 +23,10 @@
display: flex;
align-items: center;
padding-left: 20px;
+
+ @media (max-width: 769px) {
+ height: 136px;
+ }
}
&__profile__img {
@@ -18,20 +34,34 @@
height: 162px;
flex-shrink: 0;
position: relative;
- margin-right: 30px;
+ margin-right: 28px;
display: flex;
align-items: flex-end;
flex-direction: row-reverse;
+ @media (max-width: 769px) {
+ width: 80px;
+ height: 80px;
+ }
+
img {
position: absolute;
left: 0;
border-radius: 50%;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
+
+ @media (max-width: 769px) {
+ width: 80px;
+ height: 80px;
+ }
}
button {
padding: 0;
+
+ @media (max-width: 769px) {
+ margin-right: -14px;
+ }
}
&__edit {
@@ -67,6 +97,10 @@
width: 100%;
height: 100%;
+ @media (max-width: 769px) {
+ gap: 8px;
+ }
+
&__name {
color: #000;
font-family: Gmarket Sans;
@@ -74,6 +108,11 @@
font-style: normal;
font-weight: 700;
line-height: normal;
+
+ @media (max-width: 769px) {
+ font-size: 24px;
+ width: 50%;
+ }
}
.editModeOn input {
@@ -81,10 +120,13 @@
outline: none;
border-bottom: 1px solid #000;
padding-bottom: 4px;
+
+ @media (max-width: 769px) {
+ width: 100%;
+ }
}
&__talk {
- width: 278px;
height: 33px;
flex-shrink: 0;
color: #000;
@@ -98,19 +140,34 @@
width: 100%;
gap: 10px;
+ @media (max-width: 769px) {
+ line-height: 18px;
+ overflow: auto;
+ }
+
div {
display: flex;
height: 70px;
align-items: flex-end;
+ width: 92px;
+ }
+ }
+
+ .editModeOn {
+ @media (max-width: 769px) {
+ height: 100px;
}
}
.editModeOn textarea {
resize: none;
- width: 400px;
+ width: 100%;
height: 70px;
outline: none;
white-space: pre-wrap;
+ max-width: 400px;
+ border-radius: 8px;
+ padding: 2px;
}
}
@@ -127,13 +184,17 @@
border-radius: 4px;
background-color: #fff;
cursor: pointer;
+
+ @media (max-width: 769px) {
+ width: 50px;
+ }
}
.editModeOff {
- border: 1px solid #c6c6c6;
+ border: 1px solid #e3e3e3;
&:hover {
- background-color: #c6c6c6;
+ background-color: #e3e3e3;
span {
color: #fff;
@@ -182,7 +243,7 @@
.mycard {
&__container {
- width: 1200px;
+ width: 100%;
height: 392px;
flex-shrink: 0;
border-radius: 10px;
@@ -194,10 +255,17 @@
flex-direction: column;
justify-content: center;
}
+
&__top__box {
display: flex;
align-items: center;
margin-bottom: 30px;
+
+ @media (max-width: 769px) {
+ margin: 0;
+ text-align: center;
+ padding: 30px 36px;
+ }
}
&__title {
@@ -216,6 +284,10 @@
position: relative;
top: 7px;
+ @media (max-width: 769px) {
+ display: none;
+ }
+
button {
width: 99px;
height: 34px;
@@ -243,6 +315,11 @@
&__layout__box {
display: flex;
gap: 13px;
+
+ @media (max-width: 769px) {
+ max-width: 768px;
+ justify-content: center;
+ }
}
&__layout__data,
@@ -259,6 +336,18 @@
cursor: pointer;
position: relative;
+ &__slide {
+ @media (max-width: 769px) {
+ display: flex;
+ gap: 27px;
+ }
+ }
+
+ &__count {
+ margin: 20px 0;
+ text-align: center;
+ }
+
div {
color: #a5a5a5;
}
@@ -301,27 +390,48 @@
&__total__container {
margin-top: 30px;
display: flex;
- width: 1200px;
+ max-width: 1200px;
+ width: 100%;
height: 750px;
gap: 38px;
+
+ @media (max-width: 769px) {
+ flex-direction: column;
+ gap: 20px;
+ height: 100%;
+ }
}
&__left__container {
display: flex;
flex-direction: column;
gap: 30px;
+ width: 100%;
+
+ @media (max-width: 769px) {
+ gap: 20px;
+ }
}
&__posts {
- width: 596px;
+ max-width: 596px;
height: 360px;
flex-shrink: 0;
border-radius: 10px;
border: 1px solid #ebebeb;
background: #fff;
+ @media (max-width: 769px) {
+ max-width: 768px;
+ }
+
&__title {
- padding: 21px 394px 22px 22px;
+ padding: 22px 0 22px 22px;
+
+ @media (max-width: 769px) {
+ padding: 30px 36px;
+ text-align: center;
+ }
span {
color: #000;
@@ -340,6 +450,11 @@
flex-direction: column;
align-items: center;
cursor: pointer;
+ padding: 0 22px;
+
+ @media (max-width: 769px) {
+ padding: 0 20px;
+ }
&__none {
display: flex;
@@ -349,7 +464,7 @@
}
&__item {
- width: 549px;
+ width: 100%;
height: 52px;
display: flex;
align-items: center;
@@ -396,29 +511,43 @@
}
&__posts__favorite {
- width: 596px;
+ max-width: 596px;
height: 360px;
flex-shrink: 0;
border-radius: 10px;
border: 1px solid #ebebeb;
background: #fff;
+
+ @media (max-width: 769px) {
+ max-width: 768px;
+ height: 410px;
+ }
}
&__right__container {
- width: 568px;
+ max-width: 568px;
+ width: 100%;
height: 750px;
flex-shrink: 0;
- border-radius: 10.067px;
+ border-radius: 10px;
border: 1px solid #ebebeb;
background: #fff;
+
+ @media (max-width: 769px) {
+ max-width: 768px;
+ height: 436px;
+ }
}
&__liked__title {
padding: 22px 33px;
- position: sticky;
- top: 0;
- z-index: 100;
background: #fff;
+ border-radius: 10px 10px 0 0;
+
+ @media (max-width: 769px) {
+ padding: 30px 36px;
+ text-align: center;
+ }
span {
color: #000;
@@ -437,6 +566,12 @@
display: grid;
grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
+ @media (max-width: 769px) {
+ gap: 2px;
+ padding: 0 20px;
+ height: 266px;
+ }
+
span {
color: #000;
text-align: center;
@@ -463,6 +598,10 @@
display: flex;
flex-direction: column;
gap: 10px;
+
+ @media (max-width: 769px) {
+ width: 98px;
+ }
}
&__liked__pokemon {
@@ -477,10 +616,22 @@
align-items: center;
position: relative;
+ @media (max-width: 769px) {
+ width: 98px;
+ height: 98px;
+ }
+
&:hover {
transform: scale(1.05);
border: 1px solid #090909;
}
+
+ img {
+ @media (max-width: 769px) {
+ height: 80px;
+ width: 80px;
+ }
+ }
}
&__liked__cancel {
@@ -506,5 +657,23 @@
display: flex;
justify-content: flex-end;
height: 46px;
- align-items: end;
+
+ @media (max-width: 769px) {
+ justify-content: center;
+ margin-top: 20px;
+ }
+}
+
+.mobile {
+ &__overlay {
+ position: fixed;
+ top: 0;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ height: 100vh;
+ background-color: rgba(0, 0, 0, 0.4);
+ backdrop-filter: blur(1.5px);
+ z-index: 10;
+ }
}
diff --git a/src/components/mypage/Mypage.tsx b/src/components/mypage/Mypage.tsx
new file mode 100644
index 0000000..45ecb62
--- /dev/null
+++ b/src/components/mypage/Mypage.tsx
@@ -0,0 +1,16 @@
+import Introduce from '@/components/mypage/Introduce';
+import MyActive from '@/components/mypage/MyActive';
+import Mycard from '@/components/mypage/Mycard';
+import styles from './Mypage.module.scss';
+
+const Mypage = () => {
+ return (
+
+
+
+
+
+ );
+};
+
+export default Mypage;
diff --git a/src/components/skeleton/DetailImgSkeleton.tsx b/src/components/skeleton/DetailImgSkeleton.tsx
index c36c2c2..e177072 100644
--- a/src/components/skeleton/DetailImgSkeleton.tsx
+++ b/src/components/skeleton/DetailImgSkeleton.tsx
@@ -1,16 +1,25 @@
+import useCalculateInnerWidth from '@/hook/useCalculateInnerWidth';
import ContentLoader from 'react-content-loader';
const DetailImgSkeleton = () => {
+ const windowWidth = useCalculateInnerWidth();
return (
<>
-
+
>
);
diff --git a/src/components/users/MobileLogin.tsx b/src/components/users/MobileLogin.tsx
new file mode 100644
index 0000000..19e102d
--- /dev/null
+++ b/src/components/users/MobileLogin.tsx
@@ -0,0 +1,20 @@
+import { MouseEvent } from 'react';
+import SelectLogin from './SelectLogin';
+import styles from './SocialLogin.module.scss';
+
+const MobileLogin = ({
+ isOpen,
+ onLogin,
+}: {
+ isOpen?: boolean;
+ onLogin: (e: MouseEvent
) => void;
+}) => {
+ return (
+ <>
+ 로그인
+
+ >
+ );
+};
+
+export default MobileLogin;
diff --git a/src/components/users/MobileUserInfo.tsx b/src/components/users/MobileUserInfo.tsx
new file mode 100644
index 0000000..c75df44
--- /dev/null
+++ b/src/components/users/MobileUserInfo.tsx
@@ -0,0 +1,25 @@
+import SelectMyInfo from './SelectMyInfo';
+import styles from './SocialLogin.module.scss';
+
+const MobileUserInfo = ({
+ isOpen,
+ onMoveMyPage,
+ onLogout,
+}: {
+ isOpen?: boolean;
+ onMoveMyPage: () => void;
+ onLogout: () => void;
+}) => {
+ return (
+ <>
+ 나의 메뉴
+
+ >
+ );
+};
+
+export default MobileUserInfo;
diff --git a/src/components/users/SelectLogin.tsx b/src/components/users/SelectLogin.tsx
new file mode 100644
index 0000000..682952d
--- /dev/null
+++ b/src/components/users/SelectLogin.tsx
@@ -0,0 +1,49 @@
+import { MouseEvent } from 'react';
+import styles from './SocialLogin.module.scss';
+
+const SelectLogin = ({
+ isOpen,
+ onLogin,
+}: {
+ isOpen?: boolean;
+ onLogin: (e: MouseEvent) => void;
+}) => {
+ return (
+
+
+
+
+
+
+ );
+};
+
+export default SelectLogin;
diff --git a/src/components/users/SelectMyInfo.tsx b/src/components/users/SelectMyInfo.tsx
new file mode 100644
index 0000000..cb2fa2f
--- /dev/null
+++ b/src/components/users/SelectMyInfo.tsx
@@ -0,0 +1,38 @@
+import styles from './SocialLogin.module.scss';
+
+const SelectMyInfo = ({
+ isOpen,
+ onMoveMyPage,
+ onLogout,
+}: {
+ isOpen?: boolean;
+ onMoveMyPage: () => void;
+ onLogout: () => void;
+}) => {
+ return (
+
+
+
+
+
+
+ );
+};
+
+export default SelectMyInfo;
diff --git a/src/components/users/SocialLogin.module.scss b/src/components/users/SocialLogin.module.scss
index 683f43d..e1897ff 100644
--- a/src/components/users/SocialLogin.module.scss
+++ b/src/components/users/SocialLogin.module.scss
@@ -2,6 +2,11 @@
.socialLogin {
position: relative;
+ @media (max-width: 769px) {
+ width: 100%;
+ height: 100%;
+ }
+
&__loginButton {
cursor: pointer;
}
@@ -18,6 +23,20 @@
z-index: 100;
margin-top: 20px;
+ &__box {
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ gap: 12px;
+ height: 194px;
+ }
+
+ &__title {
+ width: 138px;
+ height: 40px;
+ }
+
&__visible {
display: block;
height: 81px;
@@ -28,6 +47,29 @@
gap: 4px;
align-items: center;
justify-content: center;
+
+ @media (max-width: 769px) {
+ width: 100%;
+ height: auto;
+ border: none;
+ top: 0;
+ position: relative;
+ right: 0;
+ margin: 0;
+ gap: 12px;
+ }
+ }
+
+ &__button__box {
+ height: 132px;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+
+ @media (max-width: 769px) {
+ gap: 12px;
+ }
}
&__button__mypage,
@@ -49,21 +91,87 @@
&__button__mypage {
color: #000;
+ @media (max-width: 769px) {
+ width: 180px;
+ height: 40px;
+ flex-shrink: 0;
+ border-radius: 5px;
+ font-size: 18px;
+ background-color: #000;
+ color: #fff;
+ }
+
+ &__go,
+ &__cancel {
+ width: 180px;
+ height: 40px;
+ flex-shrink: 0;
+ border-radius: 5px;
+ color: #fff;
+ text-align: center;
+ font-family: 'Gmarket Sans';
+ font-size: 18px;
+ font-style: normal;
+ font-weight: 600;
+ line-height: normal;
+ }
+
+ &__go {
+ border: 1px solid #0f60ce;
+ background: #0f60ce;
+
+ &:hover {
+ background-color: #fff;
+ color: #0f60ce;
+ }
+ }
+
+ &__cancel {
+ border: 1px solid #ff5454;
+ background: #ff5454;
+
+ &:hover {
+ background-color: #fff;
+ color: #ff5454;
+ }
+ }
+
&:hover {
border-radius: 5px;
border: 1px solid #f5f5f5;
background: #f5f5f5;
+
+ @media (max-width: 769px) {
+ border: 1px solid #000;
+ background-color: #fff;
+ color: #000;
+ }
}
}
&__button__logout {
color: #ff5454;
+ @media (max-width: 769px) {
+ width: 180px;
+ height: 40px;
+ flex-shrink: 0;
+ font-size: 18px;
+ background-color: #ff5454;
+ color: #fff;
+ border-radius: 5px;
+ }
+
&:hover {
border-radius: 5px;
border: 1px solid #ff5454;
background: #ff5454;
color: #fff;
+
+ @media (max-width: 769px) {
+ background-color: #fff;
+ color: #ff5454;
+ }
}
}
@@ -77,6 +185,7 @@
font-family: Gmarket Sans;
font-size: 12px;
font-style: normal;
+ font-family: 'Gmarket Sans';
font-weight: 600;
line-height: normal;
display: flex;
@@ -87,12 +196,6 @@
box-shadow: 0px 18px 30px 0px rgba(14, 13, 15, 0.11);
cursor: pointer;
- &__button__google span,
- &__button__github span {
- width: 100%;
- text-align: center;
- }
-
&:hover span {
display: none;
}
@@ -100,11 +203,26 @@
&__button__google {
background: #fff;
+
+ @media (max-width: 769px) {
+ width: 180px;
+ height: 40px;
+ flex-shrink: 0;
+ border: 1px solid #e0e0e0;
+ font-size: 18px;
+ }
}
&__button__github {
background: #000;
color: #fff;
+
+ @media (max-width: 769px) {
+ width: 180px;
+ height: 40px;
+ flex-shrink: 0;
+ font-size: 18px;
+ }
}
}
@@ -113,3 +231,71 @@
height: 20px;
}
}
+
+// mobile
+
+.mobile {
+ &__container {
+ width: 100%;
+ height: 100%;
+ position: fixed;
+ top: 0;
+ left: 0;
+ z-index: 1000;
+ }
+
+ &__overlay {
+ position: relative;
+ width: 100%;
+ height: 100%;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ z-index: 1001;
+ }
+
+ &__overlay.mypage {
+ position: fixed;
+ top: 0;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ height: 100vh;
+ background-color: rgba(0, 0, 0, 0.4);
+ backdrop-filter: blur(1.5px);
+ z-index: 10;
+ }
+
+ &__contents {
+ display: flex;
+ flex-direction: column;
+ z-index: 1010;
+ height: auto;
+ width: 220px;
+ justify-content: center;
+ align-items: center;
+ border-radius: 8px;
+ background: #fff;
+ box-shadow: 0px 4px 4px 0px rgba(0, 0, 0, 0.25);
+ }
+
+ &__login {
+ &__top {
+ width: 220px;
+ height: 50px;
+ flex-shrink: 0;
+ border-radius: 8px 8px 0px 0px;
+ background: #000;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ color: #ffca06;
+ text-align: center;
+ font-family: 'Gmarket Sans';
+ font-size: 22px;
+ font-style: normal;
+ font-weight: 600;
+ line-height: normal;
+ }
+ }
+}
diff --git a/src/components/users/SocialLogin.tsx b/src/components/users/SocialLogin.tsx
index 8a58c95..974c26a 100644
--- a/src/components/users/SocialLogin.tsx
+++ b/src/components/users/SocialLogin.tsx
@@ -12,6 +12,11 @@ import {
import styles from './SocialLogin.module.scss';
import useUserStore from '@/store/useUsersStore';
import { useNavigate } from 'react-router-dom';
+import SelectLogin from './SelectLogin';
+import SelectMyInfo from './SelectMyInfo';
+import useCalculateInnerWidth from '@/hook/useCalculateInnerWidth';
+import MobileLogin from './MobileLogin';
+import MobileUserInfo from './MobileUserInfo';
interface SocialLoginProps {
isOpen?: boolean;
@@ -22,6 +27,7 @@ const SocialLogin = ({ isOpen, setIsOpen }: SocialLoginProps) => {
const auth = getAuth(app);
const { user, setUser } = useUserStore();
+ const windowWidth = useCalculateInnerWidth();
const navigate = useNavigate();
useEffect(() => {
@@ -36,7 +42,7 @@ const SocialLogin = ({ isOpen, setIsOpen }: SocialLoginProps) => {
setAuthPersistence();
}, [auth]);
- const onlLogin = async (e: MouseEvent) => {
+ const onLogin = async (e: MouseEvent) => {
const target = e.target as HTMLButtonElement;
let name = target.name;
@@ -90,65 +96,29 @@ const SocialLogin = ({ isOpen, setIsOpen }: SocialLoginProps) => {
{user ? (
<>
-
내 정보
-
-
-
-
+ {windowWidth <= 768 ? (
+
+ ) : (
+
+ )}
>
) : (
<>
-
로그인
-
-
-
-
+ {windowWidth <= 768 ? (
+
+ ) : (
+
+ )}
>
)}
diff --git a/src/hook/useSlide.tsx b/src/hook/useSlide.tsx
new file mode 100644
index 0000000..4380f36
--- /dev/null
+++ b/src/hook/useSlide.tsx
@@ -0,0 +1,19 @@
+import { useState, useCallback } from 'react';
+
+const useSlide = (totalItems: number, itemsPerPage: number) => {
+ const [index, setIndex] = useState(0);
+
+ const prevSlide = useCallback(() => {
+ if (totalItems <= itemsPerPage) return;
+ setIndex((prevIndex) => (prevIndex === 0 ? totalItems - 1 : prevIndex - 1));
+ }, [totalItems, itemsPerPage]);
+
+ const nextSlide = useCallback(() => {
+ if (totalItems <= itemsPerPage) return;
+ setIndex((prevIndex) => (prevIndex === totalItems - 1 ? 0 : prevIndex + 1));
+ }, [totalItems, itemsPerPage]);
+
+ return { index, prevSlide, nextSlide };
+};
+
+export default useSlide;
diff --git a/src/pages/mypage/myPage.tsx b/src/pages/mypage/myPage.tsx
index 3804514..e0a88ed 100644
--- a/src/pages/mypage/myPage.tsx
+++ b/src/pages/mypage/myPage.tsx
@@ -1,15 +1,11 @@
import Inner from '@/components/Inner';
-import Introduce from '@/components/mypage/Introduce';
-import MyActive from '@/components/mypage/MyActive';
-import Mycard from '@/components/mypage/Mycard';
+import Mypage from '@/components/mypage/Mypage';
const myPage = () => {
return (
);
diff --git a/src/styles/global.scss b/src/styles/global.scss
index 5a14c4c..c17318b 100644
--- a/src/styles/global.scss
+++ b/src/styles/global.scss
@@ -158,6 +158,7 @@ button {
section {
margin-top: 30px;
+ margin-bottom: 40px;
}
img {