From e02569eb1708864fe23288b6c27ac3b9fe3428b1 Mon Sep 17 00:00:00 2001 From: moonseonghui Date: Thu, 21 Sep 2023 17:48:48 +0900 Subject: [PATCH 1/3] [FE] FEAT : profile layout --- frontend/src/App.tsx | 4 +- frontend/src/assets/images/link.svg | 5 + frontend/src/assets/images/profile-circle.svg | 5 + .../LeftMainNav/LeftMainNav.container.tsx | 6 + .../LeftNav/LeftMainNav/LeftMainNav.tsx | 121 ++++++++--------- frontend/src/components/LeftNav/LeftNav.tsx | 11 +- .../LeftSectionNav.container.tsx | 46 ++++++- .../LeftNav/LeftSectionNav/LeftSectionNav.tsx | 123 ++++++++++++++++-- frontend/src/pages/Layout.tsx | 3 +- frontend/src/pages/ProfilePage.tsx | 18 +++ 10 files changed, 257 insertions(+), 85 deletions(-) create mode 100644 frontend/src/assets/images/link.svg create mode 100644 frontend/src/assets/images/profile-circle.svg create mode 100644 frontend/src/pages/ProfilePage.tsx diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index c1082ea7b..ece075b5f 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -7,6 +7,7 @@ import LoginPage from "@/pages/LoginPage"; import MainPage from "@/pages/MainPage"; import AdminMainPage from "@/pages/admin/AdminMainPage"; import LoadingAnimation from "@/components/Common/LoadingAnimation"; +import ProfilePage from "./pages/ProfilePage"; const NotFoundPage = lazy(() => import("@/pages/NotFoundPage")); const LoginFailurePage = lazy(() => import("@/pages/LoginFailurePage")); @@ -28,7 +29,8 @@ function App(): React.ReactElement { } /> } /> } /> - } /> + } /> + } /> {/* admin용 라우터 */} }> diff --git a/frontend/src/assets/images/link.svg b/frontend/src/assets/images/link.svg new file mode 100644 index 000000000..bd9167557 --- /dev/null +++ b/frontend/src/assets/images/link.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/frontend/src/assets/images/profile-circle.svg b/frontend/src/assets/images/profile-circle.svg new file mode 100644 index 000000000..79107f64f --- /dev/null +++ b/frontend/src/assets/images/profile-circle.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/frontend/src/components/LeftNav/LeftMainNav/LeftMainNav.container.tsx b/frontend/src/components/LeftNav/LeftMainNav/LeftMainNav.container.tsx index 859a9b3fd..ca4c2486f 100644 --- a/frontend/src/components/LeftNav/LeftMainNav/LeftMainNav.container.tsx +++ b/frontend/src/components/LeftNav/LeftMainNav/LeftMainNav.container.tsx @@ -109,6 +109,11 @@ const LeftMainNavContainer = ({ isAdmin }: { isAdmin?: boolean }) => { closeAll(); }; + const onClickProfileButton = () => { + navigator("profile"); + closeAll(); + }; + const onClickLogoutButton = (): void => { const adminToken = isAdmin ? "admin_" : ""; if (import.meta.env.VITE_IS_LOCAL === "true") { @@ -138,6 +143,7 @@ const LeftMainNavContainer = ({ isAdmin }: { isAdmin?: boolean }) => { onClickSearchButton={onClickSearchButton} onClickLogoutButton={onClickLogoutButton} onClickClubButton={onClickClubButton} + onClickProfileButton={onClickProfileButton} isAdmin={isAdmin} /> ); diff --git a/frontend/src/components/LeftNav/LeftMainNav/LeftMainNav.tsx b/frontend/src/components/LeftNav/LeftMainNav/LeftMainNav.tsx index 5a1edc256..0b0211a6a 100644 --- a/frontend/src/components/LeftNav/LeftMainNav/LeftMainNav.tsx +++ b/frontend/src/components/LeftNav/LeftMainNav/LeftMainNav.tsx @@ -10,6 +10,7 @@ interface ILeftMainNav { onClickLentLogButton: React.MouseEventHandler; onClickSearchButton: React.MouseEventHandler; onClickClubButton: React.MouseEventHandler; + onClickProfileButton: React.MouseEventHandler; isAdmin?: boolean; } @@ -23,6 +24,7 @@ const LeftMainNav = ({ onClickLentLogButton, onClickSearchButton, onClickClubButton, + onClickProfileButton, isAdmin, }: ILeftMainNav) => { return ( @@ -58,75 +60,66 @@ const LeftMainNav = ({ {isAdmin && ( - -
- Search -
- )} - {!isAdmin && ( - -
- Log -
- )} - - -
- Contact -
-
- - {isAdmin ? ( - <> - + <> + +
+ Search +
+ +
- Club + Contact
- - ) : ( - +
Club -
- )} -
- - -
- Logout -
+ + +
+ Logout +
+ + )} + {!isAdmin && ( + <> + +
+ Profile +
+ + )}
diff --git a/frontend/src/components/LeftNav/LeftNav.tsx b/frontend/src/components/LeftNav/LeftNav.tsx index 3ff2ab2d4..4d279c753 100644 --- a/frontend/src/components/LeftNav/LeftNav.tsx +++ b/frontend/src/components/LeftNav/LeftNav.tsx @@ -2,14 +2,15 @@ import styled from "styled-components"; import LeftMainNavContainer from "@/components/LeftNav/LeftMainNav/LeftMainNav.container"; import LeftSectionNavContainer from "@/components/LeftNav/LeftSectionNav/LeftSectionNav.container"; -const LeftNav: React.FC<{ isVisible: boolean; isAdmin?: boolean }> = ({ - isAdmin, - isVisible, -}) => { +const LeftNav: React.FC<{ + isVisible: boolean; + isAdmin?: boolean; + isProfile: boolean; +}> = ({ isAdmin, isVisible, isProfile }) => { return ( - + ); }; diff --git a/frontend/src/components/LeftNav/LeftSectionNav/LeftSectionNav.container.tsx b/frontend/src/components/LeftNav/LeftSectionNav/LeftSectionNav.container.tsx index 3a48d4816..93166f559 100644 --- a/frontend/src/components/LeftNav/LeftSectionNav/LeftSectionNav.container.tsx +++ b/frontend/src/components/LeftNav/LeftSectionNav/LeftSectionNav.container.tsx @@ -1,15 +1,23 @@ +import { useLocation, useNavigate } from "react-router-dom"; import { useRecoilState, useRecoilValue } from "recoil"; import { currentSectionNameState } from "@/recoil/atoms"; import { currentFloorSectionState } from "@/recoil/selectors"; import LeftSectionNav from "@/components/LeftNav/LeftSectionNav/LeftSectionNav"; import useMenu from "@/hooks/useMenu"; -const LeftSectionNavContainer = ({ isVisible }: { isVisible: boolean }) => { +const LeftSectionNavContainer = ({ + isVisible, + isProfile, +}: { + isVisible: boolean; + isProfile: boolean; +}) => { const floorSection = useRecoilValue>(currentFloorSectionState); const [currentFloorSection, setCurrentFloorSection] = useRecoilState( currentSectionNameState ); - + const navigator = useNavigate(); + const { pathname } = useLocation(); const { closeLeftNav } = useMenu(); const onClickSection = (section: string) => { @@ -17,12 +25,44 @@ const LeftSectionNavContainer = ({ isVisible }: { isVisible: boolean }) => { setCurrentFloorSection(section); }; + const onClickProfile = () => { + closeLeftNav(); + navigator("profile"); + }; + + const onClickLentLogButton = () => { + closeLeftNav(); + navigator("profile/log"); + }; + + const onClickSlack = () => { + window.open( + "https://42born2code.slack.com/archives/C02V6GE8LD7", + "_blank", + "noopener noreferrer" + ); + }; + + const onClickClubForm = () => { + window.open( + "https://docs.google.com/forms/d/e/1FAIpQLSfp-d7qq8gTvmQe5i6Gtv_mluNSICwuv5pMqeTBqt9NJXXP7w/closedform", + "_blank", + "noopener noreferrer" + ); + }; + return ( ); }; diff --git a/frontend/src/components/LeftNav/LeftSectionNav/LeftSectionNav.tsx b/frontend/src/components/LeftNav/LeftSectionNav/LeftSectionNav.tsx index 65a8d23d9..70ebce5f6 100644 --- a/frontend/src/components/LeftNav/LeftSectionNav/LeftSectionNav.tsx +++ b/frontend/src/components/LeftNav/LeftSectionNav/LeftSectionNav.tsx @@ -6,6 +6,12 @@ interface ILeftSectionNav { onClickSection: Function; currentFloorSection: string; floorSection: string[]; + isProfile: boolean; + onClickProfile: Function; + pathname: string; + onClickLentLogButton: Function; + onClickSlack: Function; + onClickClubForm: Function; } const LeftSectionNav = ({ @@ -13,28 +19,76 @@ const LeftSectionNav = ({ currentFloorSection, onClickSection, floorSection, + isProfile, + onClickProfile, + pathname, + onClickLentLogButton, + onClickSlack, + onClickClubForm, }: ILeftSectionNav) => { return ( - - {floorSection.map((section: string, index: number) => ( + <> + + {floorSection.map((section: string, index: number) => ( + onClickSection(section)} + > + {section} + + ))} + + + + onClickSection(section)} + onClick={() => onClickProfile()} > - {section} + 내 정보 - ))} - - + onClickLentLogButton()} + > + 대여 기록 + +
+ onClickSlack()} + title="슬랙 캐비닛 채널 새창으로 열기" + > + 문의하기 + + + onClickClubForm()} + title="동아리 사물함 사용 신청서 새창으로 열기" + > + 동아리 신청서 + + + + ); }; -const LeftNavOptionStyled = styled.div<{ isVisible: boolean }>` +const LeftNavOptionStyled = styled.div<{ + isVisible: boolean; +}>` display: ${(props) => (props.isVisible ? "block" : "none")}; min-width: 240px; height: 100%; @@ -44,6 +98,26 @@ const LeftNavOptionStyled = styled.div<{ isVisible: boolean }>` position: relative; `; +const ProfileLeftNavOptionStyled = styled.div<{ + isProfile: boolean; +}>` + display: ${(props) => (props.isProfile ? "block" : "none")}; + min-width: 240px; + height: 100%; + padding: 32px 10px; + border-right: 1px solid var(--line-color); + font-weight: 300; + position: relative; + & hr { + width: 80%; + height: 1px; + background-color: #d9d9d9; + border: 0; + margin-top: 20px; + margin-bottom: 20px; + } +`; + const FloorSectionStyled = styled.div` width: 100%; height: 40px; @@ -61,4 +135,31 @@ const FloorSectionStyled = styled.div` } `; +const SectionLinkStyled = styled.div` + width: 100%; + height: 40px; + line-height: 40px; + text-indent: 20px; + margin: 2px 0; + padding-right: 30px; + cursor: pointer; + display: flex; + align-items: center; + color: var(--gray-color); + & img { + width: 15px; + height: 15px; + margin-left: auto; + } + @media (hover: hover) and (pointer: fine) { + &:hover { + color: var(--main-color); + } + &:hover img { + filter: invert(33%) sepia(55%) saturate(3554%) hue-rotate(230deg) + brightness(99%) contrast(107%); + } + } +`; + export default LeftSectionNav; diff --git a/frontend/src/pages/Layout.tsx b/frontend/src/pages/Layout.tsx index 6b53f97a2..414b260d4 100644 --- a/frontend/src/pages/Layout.tsx +++ b/frontend/src/pages/Layout.tsx @@ -29,6 +29,7 @@ const Layout = (): JSX.Element => { const isRootPath: boolean = location.pathname === "/"; const isLoginPage: boolean = location.pathname === "/login"; const isMainPage: boolean = location.pathname === "/main"; + const isProfilePage: boolean = location.pathname.includes("profile"); const openModal = () => { setIsModalOpen(true); @@ -77,7 +78,7 @@ const Layout = (): JSX.Element => { ) : ( - + diff --git a/frontend/src/pages/ProfilePage.tsx b/frontend/src/pages/ProfilePage.tsx new file mode 100644 index 000000000..a111bf2d4 --- /dev/null +++ b/frontend/src/pages/ProfilePage.tsx @@ -0,0 +1,18 @@ +import styled from "styled-components"; + +const ProfilePage = () => { + return 내 정보 여기에 넣어주세용; +}; + +const WrapperStyled = styled.div` + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + padding: 70px 0; + @media screen and (max-width: 768px) { + padding: 40px 20px; + } +`; + +export default ProfilePage; From 8c6ddee3a651ac5e0d3eddad9df9ef6a1187ef0b Mon Sep 17 00:00:00 2001 From: moonseonghui Date: Thu, 21 Sep 2023 18:01:32 +0900 Subject: [PATCH 2/3] =?UTF-8?q?[FE]=20BUG=20:=20adminLayoutPage=20isProfil?= =?UTF-8?q?e=3Dfalse=EC=86=8D=EC=84=B1=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/pages/admin/AdminLayout.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/pages/admin/AdminLayout.tsx b/frontend/src/pages/admin/AdminLayout.tsx index 57df74d38..4451d7f06 100644 --- a/frontend/src/pages/admin/AdminLayout.tsx +++ b/frontend/src/pages/admin/AdminLayout.tsx @@ -54,7 +54,7 @@ const Layout = (): JSX.Element => { ) : ( - + From d0b2b52ec970b0801351a563895c781e3c16f685 Mon Sep 17 00:00:00 2001 From: moonseonghui Date: Fri, 6 Oct 2023 19:22:44 +0900 Subject: [PATCH 3/3] =?UTF-8?q?[FE]=20FIX=20:=20isProfile=20LeftSectionNav?= =?UTF-8?q?Container=EC=97=90=EC=84=9C=20props=EB=A1=9C=20=EC=A0=84?= =?UTF-8?q?=EB=8B=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/components/LeftNav/LeftNav.tsx | 5 ++--- .../LeftSectionNav/LeftSectionNav.container.tsx | 11 +++-------- frontend/src/pages/Layout.tsx | 3 +-- frontend/src/pages/admin/AdminLayout.tsx | 2 +- 4 files changed, 7 insertions(+), 14 deletions(-) diff --git a/frontend/src/components/LeftNav/LeftNav.tsx b/frontend/src/components/LeftNav/LeftNav.tsx index 4d279c753..6aa1b8334 100644 --- a/frontend/src/components/LeftNav/LeftNav.tsx +++ b/frontend/src/components/LeftNav/LeftNav.tsx @@ -5,12 +5,11 @@ import LeftSectionNavContainer from "@/components/LeftNav/LeftSectionNav/LeftSec const LeftNav: React.FC<{ isVisible: boolean; isAdmin?: boolean; - isProfile: boolean; -}> = ({ isAdmin, isVisible, isProfile }) => { +}> = ({ isAdmin, isVisible }) => { return ( - + ); }; diff --git a/frontend/src/components/LeftNav/LeftSectionNav/LeftSectionNav.container.tsx b/frontend/src/components/LeftNav/LeftSectionNav/LeftSectionNav.container.tsx index 93166f559..93fb42c38 100644 --- a/frontend/src/components/LeftNav/LeftSectionNav/LeftSectionNav.container.tsx +++ b/frontend/src/components/LeftNav/LeftSectionNav/LeftSectionNav.container.tsx @@ -5,13 +5,7 @@ import { currentFloorSectionState } from "@/recoil/selectors"; import LeftSectionNav from "@/components/LeftNav/LeftSectionNav/LeftSectionNav"; import useMenu from "@/hooks/useMenu"; -const LeftSectionNavContainer = ({ - isVisible, - isProfile, -}: { - isVisible: boolean; - isProfile: boolean; -}) => { +const LeftSectionNavContainer = ({ isVisible }: { isVisible: boolean }) => { const floorSection = useRecoilValue>(currentFloorSectionState); const [currentFloorSection, setCurrentFloorSection] = useRecoilState( currentSectionNameState @@ -19,6 +13,7 @@ const LeftSectionNavContainer = ({ const navigator = useNavigate(); const { pathname } = useLocation(); const { closeLeftNav } = useMenu(); + const isProfilePage: boolean = location.pathname.includes("profile"); const onClickSection = (section: string) => { closeLeftNav(); @@ -55,7 +50,7 @@ const LeftSectionNavContainer = ({ { const isRootPath: boolean = location.pathname === "/"; const isLoginPage: boolean = location.pathname === "/login"; const isMainPage: boolean = location.pathname === "/main"; - const isProfilePage: boolean = location.pathname.includes("profile"); const openModal = () => { setIsModalOpen(true); @@ -78,7 +77,7 @@ const Layout = (): JSX.Element => { ) : ( - + diff --git a/frontend/src/pages/admin/AdminLayout.tsx b/frontend/src/pages/admin/AdminLayout.tsx index 4451d7f06..57df74d38 100644 --- a/frontend/src/pages/admin/AdminLayout.tsx +++ b/frontend/src/pages/admin/AdminLayout.tsx @@ -54,7 +54,7 @@ const Layout = (): JSX.Element => { ) : ( - +