diff --git a/.env.d.ts b/.env.d.ts index 59530b1..17a8293 100644 --- a/.env.d.ts +++ b/.env.d.ts @@ -1,5 +1,6 @@ declare namespace NodeJS { interface ProcessEnv { API_HOST: string + NEXT_PUBLIC_KAKAO_API_KEY: string } } diff --git a/package-lock.json b/package-lock.json index 7403e19..53a6608 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,9 +15,9 @@ "eslint-import-resolver-typescript": "^3.6.1", "next": "14.2.4", "next-auth": "^5.0.0-beta.20", - "path-to-regexp": "^7.1.0", "prettier-plugin-tailwindcss": "^0.6.5", "react": "^18", + "react-device-detect": "^2.2.3", "react-dom": "^18", "tailwind-merge": "^2.3.0", "tailwind-scrollbar-hide": "^1.1.7" @@ -17210,14 +17210,6 @@ "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", "dev": true }, - "node_modules/path-to-regexp": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-7.1.0.tgz", - "integrity": "sha512-ZToe+MbUF4lBqk6dV8GKot4DKfzrxXsplOddH8zN3YK+qw9/McvP7+4ICjZvOne0jQhN4eJwHsX6tT0Ns19fvw==", - "engines": { - "node": ">=16" - } - }, "node_modules/path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", @@ -18087,6 +18079,18 @@ "react": "^16.3.0 || ^17.0.1 || ^18.0.0" } }, + "node_modules/react-device-detect": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/react-device-detect/-/react-device-detect-2.2.3.tgz", + "integrity": "sha512-buYY3qrCnQVlIFHrC5UcUoAj7iANs/+srdkwsnNjI7anr3Tt7UY6MqNxtMLlr0tMBied0O49UZVK8XKs3ZIiPw==", + "dependencies": { + "ua-parser-js": "^1.0.33" + }, + "peerDependencies": { + "react": ">= 0.14.0", + "react-dom": ">= 0.14.0" + } + }, "node_modules/react-docgen": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/react-docgen/-/react-docgen-7.0.3.tgz", @@ -20995,6 +20999,28 @@ "node": ">=14.17" } }, + "node_modules/ua-parser-js": { + "version": "1.0.38", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.38.tgz", + "integrity": "sha512-Aq5ppTOfvrCMgAPneW1HfWj66Xi7XL+/mIy996R1/CLS/rcyJQm6QZdsKrUeivDFQ+Oc9Wyuwor8Ze8peEoUoQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/ua-parser-js" + }, + { + "type": "paypal", + "url": "https://paypal.me/faisalman" + }, + { + "type": "github", + "url": "https://github.com/sponsors/faisalman" + } + ], + "engines": { + "node": "*" + } + }, "node_modules/ufo": { "version": "1.5.3", "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.5.3.tgz", diff --git a/package.json b/package.json index 4e1011d..8fcb54e 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,7 @@ "next-auth": "^5.0.0-beta.20", "prettier-plugin-tailwindcss": "^0.6.5", "react": "^18", + "react-device-detect": "^2.2.3", "react-dom": "^18", "tailwind-merge": "^2.3.0", "tailwind-scrollbar-hide": "^1.1.7" diff --git a/public/icons/download.svg b/public/icons/download.svg new file mode 100644 index 0000000..9fc4a4a --- /dev/null +++ b/public/icons/download.svg @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/public/icons/error.svg b/public/icons/error.svg new file mode 100644 index 0000000..0924e70 --- /dev/null +++ b/public/icons/error.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/public/icons/sketchIcons-paperclip.svg b/public/icons/sketchIcons-paperclip.svg new file mode 100644 index 0000000..4cca92b --- /dev/null +++ b/public/icons/sketchIcons-paperclip.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/icons/sns/sns-facebook.svg b/public/icons/sns/sns-facebook.svg new file mode 100644 index 0000000..e19134d --- /dev/null +++ b/public/icons/sns/sns-facebook.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/public/icons/sns/sns-ig-bg.png b/public/icons/sns/sns-ig-bg.png new file mode 100644 index 0000000..1cc2441 Binary files /dev/null and b/public/icons/sns/sns-ig-bg.png differ diff --git a/public/icons/sns/sns-ig.svg b/public/icons/sns/sns-ig.svg new file mode 100644 index 0000000..458e3b8 --- /dev/null +++ b/public/icons/sns/sns-ig.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/public/icons/sns/sns-kakao.svg b/public/icons/sns/sns-kakao.svg new file mode 100644 index 0000000..4270d6c --- /dev/null +++ b/public/icons/sns/sns-kakao.svg @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/public/icons/sns/sns-x.svg b/public/icons/sns/sns-x.svg new file mode 100644 index 0000000..9a8d05c --- /dev/null +++ b/public/icons/sns/sns-x.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/app/(board)/board/[boardId]/_components/Share/Section.tsx b/src/app/(board)/board/[boardId]/_components/Share/Section.tsx new file mode 100644 index 0000000..d47c71f --- /dev/null +++ b/src/app/(board)/board/[boardId]/_components/Share/Section.tsx @@ -0,0 +1,49 @@ +import { ComponentProps, MouseEventHandler, ReactNode } from 'react' +import { twMerge } from 'tailwind-merge' + +interface SectionProps { + title: string + children: ReactNode +} + +const Section = ({ title, children }: SectionProps) => ( +
+

{title}

+
+ {children} +
+
+) + +const Item = ({ + icon, + desc = '', + bg = '', + onClick = () => {}, +}: { + icon: ReactNode + desc?: string + bg?: ComponentProps<'div'>['className'] + onClick?: MouseEventHandler +}) => { + return ( + + ) +} + +Section.Item = Item +export default Section diff --git a/src/app/(board)/board/[boardId]/_components/Share/index.tsx b/src/app/(board)/board/[boardId]/_components/Share/index.tsx new file mode 100644 index 0000000..c136565 --- /dev/null +++ b/src/app/(board)/board/[boardId]/_components/Share/index.tsx @@ -0,0 +1,95 @@ +'use client' + +import Modal from '@/components/Modal' +import CopyIcon from 'public/icons/copy.svg' +import Share from 'public/icons/ios_share.svg' +import TwoPolaroidsIcon from 'public/icons/linkShare.svg' +import { useEffect, useState } from 'react' +import DownloadIcon from 'public/icons/download.svg' +import KakaoIcon from 'public/icons/sns/sns-kakao.svg' +import IGIcon from 'public/icons/sns/sns-ig.svg' +import XIcon from 'public/icons/sns/sns-x.svg' +import FacebookIcon from 'public/icons/sns/sns-facebook.svg' +import Section from './Section' +import { useTutorial } from '../Tutorial/TutorialContext' +import useSnsShare from '../../_hooks/useSnsShare' + +const ShareBtn = () => { + const [showShareModal, setShowShareModal] = useState(false) + const [currentURL, setCurrentURL] = useState('') + const { shareToKakao, shareToInsta, shareToFacebook, shareToX } = + useSnsShare() + + useEffect(() => { + setCurrentURL(window.location.href) + }, []) + + const copyLink = () => { + return navigator.clipboard.writeText(currentURL) + } + + const { run, nextStep } = useTutorial() + + const handleClose = () => { + setShowShareModal(false) + if (run) { + nextStep() + } + } + + const handleShare = (shareFn: () => void) => { + shareFn() + setShowShareModal(false) + } + + return ( + <> + setShowShareModal(true)} className="w-6" /> + + + }> + + 보드를 친구에게 공유해보세요! +
+
+ } + bg="bg-gray-900" + desc="링크 복사" + onClick={() => handleShare(copyLink)} + /> + } + bg="bg-kakao" + desc="카카오톡" + onClick={() => handleShare(shareToKakao)} + /> + } + bg="bg-[url('/icons/sns/sns-ig-bg.png')]" + desc="인스타그램" + onClick={() => handleShare(shareToInsta)} + /> + } + bg="bg-[#000]" + desc="X" + onClick={() => handleShare(shareToX)} + /> + } + bg="bg-facebook" + desc="페이스북" + onClick={() => handleShare(shareToFacebook)} + /> +
+
+ } bg="bg-gray-200" /> +
+ + + + ) +} + +export default ShareBtn diff --git a/src/app/(board)/board/[boardId]/_components/ShareBtn.tsx b/src/app/(board)/board/[boardId]/_components/ShareBtn.tsx deleted file mode 100644 index 8c78234..0000000 --- a/src/app/(board)/board/[boardId]/_components/ShareBtn.tsx +++ /dev/null @@ -1,57 +0,0 @@ -'use client' - -import Modal from '@/components/Modal' -import CopyIcon from 'public/icons/copy.svg' -import Share from 'public/icons/ios_share.svg' -import TwoPolaroidsIcon from 'public/icons/twopolaroids.svg' -import { useEffect, useState } from 'react' -import { useTutorial } from './Tutorial/TutorialContext' - -const ShareBtn = () => { - const [showShareModal, setShowShareModal] = useState(false) - const [currentURL, setCurrentURL] = useState('') - - useEffect(() => { - setCurrentURL(window.location.href) - }, []) - - const copyLink = () => { - return navigator.clipboard.writeText(currentURL) - } - - const { run, nextStep } = useTutorial() - const handleClose = () => { - setShowShareModal(false) - if (run) { - nextStep() - } - } - - return ( - <> - setShowShareModal(true)} className="w-6" /> - - - }> - - 보드를 친구에게 공유해보세요! - -
{currentURL}
-
- - - - 복사하기 - - } - onConfirm={copyLink} - /> -
-
- - ) -} - -export default ShareBtn diff --git a/src/app/(board)/board/[boardId]/_hooks/useSnsShare.ts b/src/app/(board)/board/[boardId]/_hooks/useSnsShare.ts new file mode 100644 index 0000000..9cac3a9 --- /dev/null +++ b/src/app/(board)/board/[boardId]/_hooks/useSnsShare.ts @@ -0,0 +1,83 @@ +'use client' + +import { useEffect } from 'react' +import { isDevMode } from '@/lib/utils/env' +import { isIOS, isAndroid } from 'react-device-detect' + +const useSnsShare = () => { + useEffect(() => { + const script = document.createElement('script') + script.src = 'https://t1.kakaocdn.net/kakao_js_sdk/2.7.2/kakao.min.js' + script.async = true + script.integrity = + 'sha384-TiCUE00h649CAMonG018J2ujOgDKW/kVWlChEuu4jK2vxfAAD0eZxzCKakxg55G4' + script.crossOrigin = 'anonymous' + + document.body.appendChild(script) + + return () => { + document.body.removeChild(script) + } + }, []) + + const shareToKakao = () => { + const { Kakao, location } = window + if (Kakao === undefined) { + return + } + + if (!Kakao.isInitialized()) { + Kakao.init(process.env.NEXT_PUBLIC_KAKAO_API_KEY) + } + + Kakao.Share.sendDefault({ + objectType: 'feed', + content: { + title: 'POLABO | 함께 꾸미는 폴라로이드 보드, 폴라보', + description: '내 보드를 우리의 소중한 추억들로 꾸며줘!', + imageUrl: '/images/opengraph-image.png', + link: { + mobileWebUrl: isDevMode + ? 'https://dev.polabo.site' + : 'https://polabo.site', + webUrl: isDevMode ? 'https://dev.polabo.site' : 'https://polabo.site', + }, + }, + buttons: [ + { + title: '웹으로 보기', + link: { + mobileWebUrl: location.href, + webUrl: location.href, + }, + }, + ], + }) + } + + const shareToInsta = () => { + let url + if (isIOS) { + url = 'https://www.instagram.com/create/story' + } else if (isAndroid) { + url = + 'intent://instagram.com/#Intent;scheme=https;package=com.instagram.android;end' + } else { + url = 'https://www.instagram.com/' + } + + window.open(url) + } + + const shareToFacebook = () => { + window.open(`https://www.facebook.com/sharer.php?u=${window.location.href}`) + } + + const shareToX = () => { + window.open(`https://twitter.com/intent/tweet?url=${window.location.href}`) + } + + return { shareToKakao, shareToInsta, shareToFacebook, shareToX } +} + +export default useSnsShare diff --git a/src/app/(board)/board/[boardId]/page.tsx b/src/app/(board)/board/[boardId]/page.tsx index 4360153..ca96e97 100644 --- a/src/app/(board)/board/[boardId]/page.tsx +++ b/src/app/(board)/board/[boardId]/page.tsx @@ -9,7 +9,7 @@ import CreatePolaroid from './_components/CreatePolaroidModal' import { ModalProvider } from './_components/CreatePolaroidModal/ModalContext' import Empty from './_components/Empty' import OpenModalBtn from './_components/OpenModalBtn' -import ShareBtn from './_components/ShareBtn' +import ShareBtn from './_components/Share' import Tutorial from './_components/Tutorial' import { Step1Tooltip } from './_components/Tutorial/Tooltips' import { TutorialProvider } from './_components/Tutorial/TutorialContext' diff --git a/src/app/error.tsx b/src/app/error.tsx index 643b23b..4681698 100644 --- a/src/app/error.tsx +++ b/src/app/error.tsx @@ -1,9 +1,20 @@ 'use client' +import Button from '@/components/Button' +import { useRouter } from 'next/navigation' +import ErrorIcon from 'public/icons/error.svg' + const ErrorPage = () => { + const router = useRouter() return (
-

오류가 발생했어요.

+ +

오류가 발생했어요.

+

사용에 불편을 드려 죄송합니다.

+

+ (이 화면을 덜 보시도록 폴라보팀은 매일 노력하고있어요..!) +

+
) } diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 76aaf4f..3628530 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -44,6 +44,13 @@ export const metadata: Metadata = { }, } +declare global { + interface Window { + /* eslint-disable-next-line @typescript-eslint/no-explicit-any */ + Kakao: any + } +} + export default function RootLayout({ children, }: Readonly<{ diff --git a/src/app/mypage/_components/GotoBoardsBtn.tsx b/src/app/mypage/_components/GotoBoardsBtn.tsx new file mode 100644 index 0000000..77d293e --- /dev/null +++ b/src/app/mypage/_components/GotoBoardsBtn.tsx @@ -0,0 +1,67 @@ +import Link from 'next/link' +import { ReactNode } from 'react' +import { twMerge } from 'tailwind-merge' +import MyBoardIcon from 'public/icons/sketchIcons-4.svg' +import JoinedBoardIcon from 'public/icons/sketchIcons-1.svg' +import { getMyBoards } from '@/lib' + +interface GoToBoardsBtnProps { + name: string + icon: ReactNode + number: number + className?: React.ComponentProps<'a'>['className'] +} + +const GoToBoardsBtn = ({ + name, + icon, + number, + className = '', +}: GoToBoardsBtnProps) => { + return ( + // TODO: JoinedBoard는 /mypage/boards 두번째 탭으로 이동 + +
+
+ {icon} +
+ {name} + {number} +
+ + ) +} + +export const MyBoard = async () => { + const { + pagination: { totalCount }, + } = await getMyBoards() + return ( +
+ } + number={totalCount} + className="-rotate-[5deg] transform" + /> +
+ ) +} + +export const JoinedBoard = () => { + return ( +
+ } + number={23} + className="rotate-[3deg] transform" + /> +
+ ) +} diff --git a/src/app/mypage/_components/ProfilePic.tsx b/src/app/mypage/_components/ProfilePic.tsx new file mode 100644 index 0000000..8b4b237 --- /dev/null +++ b/src/app/mypage/_components/ProfilePic.tsx @@ -0,0 +1,11 @@ +import DefaultPic from 'public/icons/surprised.svg' + +const ProfilePic = () => { + return ( +
+ +
+ ) +} + +export default ProfilePic diff --git a/src/app/mypage/page.tsx b/src/app/mypage/page.tsx new file mode 100644 index 0000000..9c9acc2 --- /dev/null +++ b/src/app/mypage/page.tsx @@ -0,0 +1,47 @@ +import { auth } from '@/auth' +import MenuLink from '@/components/Menu/MenuLink' +import ExternalLinkContainer from '@/components/Menu/ExternalLinkContainer' +import Header from '@/components/Header' +import PinIcon from 'public/icons/sketchIcons-4.svg' +import ClipIcon from 'public/icons/sketchIcons-paperclip.svg' +import { JoinedBoard, MyBoard } from './_components/GotoBoardsBtn' +import ProfilePic from './_components/ProfilePic' + +const MyPage = async () => { + const session = await auth() + + return ( +
+
} /> +
+ +
+ {session?.profile.nickName} +
+
+ + +
+
+
+
+
+ } + text="프로필 수정" + linkTo="/mypage/profileEdit" + /> + } + text="내 보드 목록" + linkTo="/mypage/boards" + /> +
+
+ +
+
+ ) +} + +export default MyPage diff --git a/src/components/HamburgerMenu/Menu.tsx b/src/components/HamburgerMenu/Menu.tsx deleted file mode 100644 index 81957c9..0000000 --- a/src/components/HamburgerMenu/Menu.tsx +++ /dev/null @@ -1,158 +0,0 @@ -import { signOut, useSession } from 'next-auth/react' -import Link from 'next/link' -import { usePathname } from 'next/navigation' -import LogoutModalIcon from 'public/icons/linkShare.svg' -import PersonIcon from 'public/icons/person.svg' -import PinIcon from 'public/icons/pinFilled.svg' -import PolaroidIcon from 'public/icons/polaroid.svg' -import { ReactNode, useState } from 'react' -import Modal from '../Modal' -import { useDrawer } from './DrawerContext' - -const Profile = ({ - onClick, -}: { - onClick: React.ComponentProps<'div'>['onClick'] -}) => { - const { data: session, status } = useSession() - return ( -
- - {status === 'authenticated' ? ( - - {session.profile.nickName} - - ) : ( - - 로그인해주세요. - - )} -
- ) -} - -const Main = () => { - const pathName = usePathname() - const { setClose } = useDrawer() - return ( - { - if (pathName === '/') { - setClose() - } - }} - > - POLABO 메인 - - ) -} - -const Divider = () =>
- -const MyMenu = ({ - icon, - text, - linkTo, -}: { - icon: ReactNode - text: string - linkTo: string -}) => ( - - {icon} - {text} - -) - -const ServiceMenu = ({ text, linkTo }: { text: string; linkTo: string }) => ( - - {text} - -) - -const Logout = () => { - const [isOpen, setIsOpen] = useState(false) - return ( - <> -
setIsOpen(true)} - > - 로그아웃 -
- setIsOpen(false)}> - }> - - 로그아웃 하시겠습니까? - { - signOut({ callbackUrl: '/' }) - }} - /> - - - - ) -} - -const Menu = () => { - const { status } = useSession() - - return ( -
- {}} /> -
- - {status === 'authenticated' && ( -
- } - text="프로필 수정" - linkTo="/mypage/profileEdit" - /> - } - text="내 보드 목록" - linkTo="/mypage/boards" - /> -
- )} - -
- - - - -
- - {status === 'authenticated' && } -
- ) -} - -export default Menu diff --git a/src/components/HamburgerMenu/index.tsx b/src/components/HamburgerMenu/index.tsx index 875b27c..a134ccf 100644 --- a/src/components/HamburgerMenu/index.tsx +++ b/src/components/HamburgerMenu/index.tsx @@ -3,7 +3,7 @@ import HamburgerIcon from 'public/icons/hamburger.svg' import { useState } from 'react' import Drawer from './Drawer' -import Menu from './Menu' +import Menu from '../Menu' import { DrawerProvider } from './DrawerContext' const Hamburger = ({ diff --git a/src/components/Menu/ExternalLinkContainer.tsx b/src/components/Menu/ExternalLinkContainer.tsx new file mode 100644 index 0000000..845669f --- /dev/null +++ b/src/components/Menu/ExternalLinkContainer.tsx @@ -0,0 +1,35 @@ +import Link from 'next/link' +import { twMerge } from 'tailwind-merge' + +const ExternalLink = ({ text, linkTo }: { text: string; linkTo: string }) => ( + + {text} + +) + +const ExternalLinkContainer = ({ + className = '', +}: { + className?: React.ComponentProps<'div'>['className'] +}) => ( +
+ + + + +
+) + +export default ExternalLinkContainer diff --git a/src/components/Menu/MenuLink.tsx b/src/components/Menu/MenuLink.tsx new file mode 100644 index 0000000..3348eba --- /dev/null +++ b/src/components/Menu/MenuLink.tsx @@ -0,0 +1,22 @@ +import Link from 'next/link' +import { ReactNode } from 'react' + +const MenuLink = ({ + icon, + text, + linkTo, +}: { + icon: ReactNode + text: string + linkTo: string +}) => ( + + {icon} + {text} + +) + +export default MenuLink diff --git a/src/components/Menu/index.tsx b/src/components/Menu/index.tsx new file mode 100644 index 0000000..151cb33 --- /dev/null +++ b/src/components/Menu/index.tsx @@ -0,0 +1,91 @@ +import { signOut, useSession } from 'next-auth/react' +import Link from 'next/link' +import { usePathname } from 'next/navigation' +import LogoutModalIcon from 'public/icons/linkShare.svg' +import PersonIcon from 'public/icons/person.svg' +import PinIcon from 'public/icons/pinFilled.svg' +import PolaroidIcon from 'public/icons/polaroid.svg' +import { useState } from 'react' +import Modal from '../Modal' +import { useDrawer } from '../HamburgerMenu/DrawerContext' +import MenuLink from './MenuLink' +import ExternalLinkContainer from './ExternalLinkContainer' + +const Profile = () => { + const { data: session, status } = useSession() + return ( + + + + {status === 'authenticated' + ? session?.profile.nickName + : '로그인해주세요.'} + + + ) +} + +const Divider = () =>
+ +const Logout = () => { + const [isOpen, setIsOpen] = useState(false) + return ( + <> +
setIsOpen(true)} + > + 로그아웃 +
+ setIsOpen(false)}> + }> + + 로그아웃 하시겠습니까? + { + signOut({ callbackUrl: '/' }) + }} + /> + + + + ) +} + +const Menu = () => { + const { status } = useSession() + const pathName = usePathname() + const { setClose } = useDrawer() + + return ( +
+
+ +
{ + if (pathName === '/') { + setClose() + } + }} + > + } text="POLABO 메인" linkTo="/" /> +
+ {status === 'authenticated' && ( + } text="마이페이지" linkTo="/mypage" /> + )} +
+ + + + + {status === 'authenticated' && } +
+ ) +} + +export default Menu diff --git a/src/components/Modal/index.tsx b/src/components/Modal/index.tsx index dc2e084..9f8db63 100644 --- a/src/components/Modal/index.tsx +++ b/src/components/Modal/index.tsx @@ -106,10 +106,10 @@ const BottomModal = ({ const { isVisible } = useContext(ModalContext) return (
{icon && ( -
{icon}
+
{icon}
)}
{children} diff --git a/tailwind.config.ts b/tailwind.config.ts index f6d369e..7e4e0fb 100644 --- a/tailwind.config.ts +++ b/tailwind.config.ts @@ -29,6 +29,7 @@ const config: Config = { negative: '#ef4444', transparent: 'transparent', kakao: '#FEE500', + facebook: '#337FFF', }, fontSize: { xxs: '10px', @@ -116,6 +117,8 @@ const config: Config = { button: '0px 4px 8px 0px rgba(0, 0, 0, 0.15)', signupGenderBtn: '2px 4px 0px 0px rgba(0, 0, 0, 0.30)', popup: '0px 4px 8px 0px rgba(0, 0, 0, 0.15)', + myPageBox: + '0px 1px 1px 0px rgba(0, 0, 0, 0.25), 0px 2px 4px 0px rgba(0, 0, 0, 0.25)', }, }, },