diff --git a/package-lock.json b/package-lock.json index ac81172..59cebf4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2623,13 +2623,6 @@ "dev": true, "license": "ISC" }, - "node_modules/jquery": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.7.1.tgz", - "integrity": "sha512-m4avr8yL8kmFN8psrbFFFmB/If14iN5o9nw/NgnnM+kybDJpRsAynV2BsfpTYrTRysYUdADVD7CkUUizgkpLfg==", - "license": "MIT", - "peer": true - }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", diff --git a/src/components/Header/Header.tsx b/src/components/Header/Header.tsx index 30e4d58..f6d7acb 100644 --- a/src/components/Header/Header.tsx +++ b/src/components/Header/Header.tsx @@ -1,8 +1,10 @@ -import { useCallback } from 'react'; +import { useCallback, useState } from 'react'; import { useNavigate } from 'react-router'; import * as S from './Header.styled'; +import Popup from '../Popup/Popup'; export default function Header() { + const [isPopupOpen, setPopupOpen] = useState(false); const navigate = useNavigate(); const onContainerClick = useCallback(() => { }, []); @@ -15,13 +17,13 @@ export default function Header() { navigate('/')}> 홈 - navigate('/blog-project')}> + setPopupOpen(true)}> 블로그 / 프로젝트 - navigate('/news')}> + setPopupOpen(true)}> 소식 - navigate('/faq')}> + setPopupOpen(true)}> FAQ navigate('/apply')}> @@ -31,6 +33,13 @@ export default function Header() { {/* 파밍로그 버튼 */} 파밍로그 + + setPopupOpen(false)} + title={"아직 오픈되지 않았습니다."} + content={"오픈픈 예정: 2025년 4월"} + /> ); } diff --git a/src/components/Popup/Popup.styled.tsx b/src/components/Popup/Popup.styled.tsx new file mode 100644 index 0000000..71bf83d --- /dev/null +++ b/src/components/Popup/Popup.styled.tsx @@ -0,0 +1,50 @@ +import styled from 'styled-components'; + +export const PopupOverlay = styled.div` + position: fixed; + inset: 0; + background: rgba(113, 113, 113, 0.3); + display: flex; + align-items: center; + justify-content: center; + z-index: 9999; +`; + +export const PopupBox = styled.div` + width: 500px; + background-color: #fcfcfc; + border: 3px solid #28723f; + border-radius: 15px; + text-align: center; + padding: 40px; + z-index: 10000; +`; + +export const PopupTitle = styled.p` + font-size: 22px; + font-weight: 700; + color: black; + margin-bottom: 20px; +`; + +export const PopupText = styled.p` + font-size: 18px; + color: black; + margin-bottom: 20px; +`; + +export const PopupCloseButton = styled.button` + background-color: #28723f; + color: #fcfcfc; + font-size: 16px; + padding: 10px 20px; + border: none; + border-radius: 10px; + cursor: pointer; + box-shadow: 0px 2px 10px rgba(25, 25, 25, 0.2); + width: 100px; + margin-top: 20px; + &:hover { + background-color: #1f5b30; + } +`; diff --git a/src/components/Popup/Popup.tsx b/src/components/Popup/Popup.tsx new file mode 100644 index 0000000..ad4462d --- /dev/null +++ b/src/components/Popup/Popup.tsx @@ -0,0 +1,25 @@ +import React from 'react'; +import * as S from './Popup.styled'; + +interface PopupProps { + isOpen: boolean; + onClose: () => void; + title: string; + content: string; +} + +const Popup: React.FC = ({ isOpen, onClose, title, content }) => { + if (!isOpen) return null; + + return ( + + e.stopPropagation()}> + {title} + {content} + 확인 + + + ); +}; + +export default Popup; \ No newline at end of file diff --git a/src/pages/Main/Achievements/Achievements.styles.ts b/src/pages/Main/Achievements/Achievements.styles.ts index d601f54..8130352 100644 --- a/src/pages/Main/Achievements/Achievements.styles.ts +++ b/src/pages/Main/Achievements/Achievements.styles.ts @@ -6,6 +6,8 @@ export const AchievementsContainer = styled.div` padding: 60px 0; text-align: center; overflow-x: hidden; + position: relative; + z-index: 0; `; export const Title = styled.h2` font-size: 48px; @@ -25,6 +27,7 @@ export const SliderWrapper = styled.div` width: 100vw; position: relative; /* 블러 효과 위치 */ overflow: visible; + z-index: 0; .slick-list { width: 100vw; @@ -50,9 +53,9 @@ export const SliderWrapper = styled.div` content: ""; position: absolute; top: 0; - width: 400px; /* 블러 영역 너비 -> 뷰 포인트에 따라 조절 필요*/ + width: 400px; //블러 영역 너비 -> 뷰 포인트에 따라 조절 필요 height: 100%; - z-index: 2; + z-index: 1; pointer-events: none; } diff --git a/src/pages/Main/BottomInfo/BottomInfo.tsx b/src/pages/Main/BottomInfo/BottomInfo.tsx index f78a972..36f5747 100644 --- a/src/pages/Main/BottomInfo/BottomInfo.tsx +++ b/src/pages/Main/BottomInfo/BottomInfo.tsx @@ -4,6 +4,7 @@ import GitHubIcon from '@/assets/githubLogo2.png'; import InstagramIcon from '@/assets/InstagramLogo2.png'; import LinktreeIcon from '@/assets/LinktreeLogo.png'; import DGUIcon from "@/assets/DGULogo.png" +import Popup from '@/components/Popup/Popup'; const BottomInfo = () => { const [isPopupOpen, setPopupOpen] = useState(false); @@ -64,16 +65,12 @@ const BottomInfo = () => { - {/* 팝업 -> 나중에 공용 컴포넌트로 뺄까 고민 중*/} - {isPopupOpen && ( - setPopupOpen(false)}> - e.stopPropagation()}> - 지금은 모집 기간이 아닙니다. - 공개 모집 예정: 2025년 2월 - setPopupOpen(false)}>확인 - - - )} + setPopupOpen(false)} + title={"지금은 모집 기간이 아닙니다."} + content={"공개 모집 예정: 2025년 2월"} + /> ); }; diff --git a/src/pages/Main/FarmSyetemNav/FarmSystemNav.styled.ts b/src/pages/Main/FarmSyetemNav/FarmSystemNav.styled.ts index fb9bab5..b9b055b 100644 --- a/src/pages/Main/FarmSyetemNav/FarmSystemNav.styled.ts +++ b/src/pages/Main/FarmSyetemNav/FarmSystemNav.styled.ts @@ -1,9 +1,21 @@ import styled from 'styled-components'; +interface FixedNavProps { + isVisible: boolean; +} + +export const FixedNavWrapper = styled.div` + position: fixed; + top: ${({ isVisible }) => (isVisible ? "10px" : "-50px")}; + right: 20px; + transition: top 0.3s ease-in-out; + z-index: 1000; +`; + export const Navbar = styled.nav` - background-color: #216D35; + background-color: #216D35; padding: 10px 20px; - border-radius: 20px; + border-radius: 17px; display: flex; align-items: center; gap: 20px; @@ -14,7 +26,18 @@ export const NavItem = styled.a` font-size: 14px; text-decoration: none; font-weight: 500; - + display: flex; + align-items: center; + &:first-child { - font-weight: bold; + font-weight: bold; + } +`; + +export const Circle = styled.div` + width: 5px; + height: 5px; + background-color: white; + border-radius: 50%; + margin-right: 8px; `; diff --git a/src/pages/Main/FarmSyetemNav/FarmSystemNav.tsx b/src/pages/Main/FarmSyetemNav/FarmSystemNav.tsx index d86ba08..a7be6f7 100644 --- a/src/pages/Main/FarmSyetemNav/FarmSystemNav.tsx +++ b/src/pages/Main/FarmSyetemNav/FarmSystemNav.tsx @@ -1,12 +1,52 @@ import * as S from './FarmSystemNav.styled'; +import { useState, useEffect } from 'react'; export default function FarmSystemNav() { + const [isVisible, setIsVisible] = useState(false); + + useEffect(() => { + const handleScroll = () => { + if (window.scrollY > 200) { + setIsVisible(true); + } else { + setIsVisible(false); + } + }; + + window.addEventListener("scroll", handleScroll); + return () => { + window.removeEventListener("scroll", handleScroll); + }; + }, []); + + const handleSmoothScroll = (event: React.MouseEvent, targetId: string) => { + event.preventDefault(); + const targetElement = document.querySelector(targetId); + if (targetElement) { + window.scrollTo({ + top: targetElement.getBoundingClientRect().top + window.scrollY, + behavior: "smooth", + }); + } + }; + + return ( - - ● Farm System이란? - ● 트랙 및 커리큘럼 - ● 활동 및 성과 - ● 지원 요건 - + + + handleSmoothScroll(e, "#about")}> + Farm System이란? + + handleSmoothScroll(e, "#tracks")}> + 트랙 및 커리큘럼 + + handleSmoothScroll(e, "#achievements")}> + 활동 및 성과 + + handleSmoothScroll(e, "#eligibility")}> + 지원 요건 + + + ); -} +} \ No newline at end of file diff --git a/src/pages/Main/Intro/Intro.tsx b/src/pages/Main/Intro/Intro.tsx index f57bd28..c10043c 100644 --- a/src/pages/Main/Intro/Intro.tsx +++ b/src/pages/Main/Intro/Intro.tsx @@ -1,16 +1,12 @@ import * as S from './Intro.styled.tsx'; import logo from '../../../assets/FarmLogo.png'; import { useState } from 'react'; -import FarmSystemNav from '../FarmSyetemNav/FarmSystemNav.tsx'; +import Popup from '@/components/Popup/Popup.tsx'; const Intro = () => { const [isPopupOpen, setPopupOpen] = useState(false); return ( - {/* 네비게이션을 오른쪽 정렬하기 위한 래퍼 */} - - - 🌱 @@ -32,16 +28,12 @@ const Intro = () => { 2025년 2월 공개 모집 예정 - {/* 팝업 수빈님 것과 통일 */} - {isPopupOpen && ( - setPopupOpen(false)}> - e.stopPropagation()}> - 지금은 모집 기간이 아닙니다. - 공개 모집 예정: 2025년 2월 - setPopupOpen(false)}>확인 - - - )} + setPopupOpen(false)} + title={"지금은 모집 기간이 아닙니다."} + content={"공개 모집 예정: 2025년 2월"} + /> ); }; diff --git a/src/pages/Main/Tracks/InfoBox.styled.ts b/src/pages/Main/Tracks/InfoBox.styled.ts index b56f1f3..a75875c 100644 --- a/src/pages/Main/Tracks/InfoBox.styled.ts +++ b/src/pages/Main/Tracks/InfoBox.styled.ts @@ -36,10 +36,10 @@ export const TrackDescription = styled.p` width: 1040px; height: 200px; color: var(--FarmSystem_Black, #191919); - font-size: 20px; + font-size: 19px; font-style: normal; - font-weight: 500; - line-height: 30px; /* 150% */ + font-weight: 300; + line-height: 35px; /* 150% */ `; export const PhasesContainer = styled.div` @@ -83,7 +83,7 @@ export const PhaseContent = styled.ul` justify-content: center; color: var(--FarmSystem_Black, #191919); - font-size: 20px; + font-size: 18px; font-style: normal; font-weight: 400; line-height: 30px; /* 150% */ @@ -114,10 +114,11 @@ export const ProfessorText = styled.p` `; export const ProfessorName = styled.p` - color: var(--FarmSystem_Black, #191919); + width: 100%; + color: #404040; font-size: 24px; font-style: normal; - font-weight: 500; + font-weight: 700; line-height: 29px; /* 120.833% */ `; @@ -130,21 +131,52 @@ export const ProfessorProfile = styled.div` gap: 38px; `; +export const ProfessorProfileContent = styled.div` + width: 180px; + height: 180px; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; +`; + export const ProfessorImage = styled.img` - width: 100px; - height: 100px; + width: 120px; + height: 120px; flex-shrink: 0; aspect-ratio: 1/1; + border-radius: 10px; +`; + +export const HomepageButton = styled.a` + background-color: #FCFCFC; + color: #404040; + font-size: 13px; + font-weight: bold; + padding: 5px 17px; + border-radius: 8px; + text-decoration: none; + text-align: center; + margin-top: 15px; + display: inline-block; + &:hover { + background-color: #E1E1E1; + } +`; + +export const ProfessorContent = styled.div` + width: 100%; + height: 160px; `; export const ProfileList = styled.ul` list-style-type: none; list-style-position: inside; - display: grid; - grid-template-columns: repeat(2, 1fr); + grid-template-columns: 1fr 1.5fr; column-gap: 30px; row-gap: 15px; + margin-top: 20px; `; export const ProfileListItem = styled.li` @@ -154,19 +186,27 @@ export const ProfileListItem = styled.li` align-items: center; `; +export const ProfileInfo = styled.p` + color: #635C55; + font-size: 16px; + font-style: normal; + font-weight: 500; + line-height: 15px; /* 100% */ +`; + export const ProfileListKey = styled.p` color: var(--FarmSystem_Black, #191919); - font-size: 20px; + font-size: 18px; font-style: normal; font-weight: 500; line-height: 20px; /* 100% */ `; export const ProfileListValue = styled.p` - width: 300px; + width: 70%; flex-shrink: 0; color: var(--FarmSystem_Black, #191919); - font-size: 20px; + font-size: 18px; font-style: normal; font-weight: 400; line-height: 20px; /* 100% */ diff --git a/src/pages/Main/Tracks/InfoBox.tsx b/src/pages/Main/Tracks/InfoBox.tsx index eb06f05..7fe8383 100644 --- a/src/pages/Main/Tracks/InfoBox.tsx +++ b/src/pages/Main/Tracks/InfoBox.tsx @@ -36,37 +36,44 @@ export default function InfoBox({ selectedTrack }: InfoBoxProps) { {/* 담당 교수 정보 */} 담당 교수 - {selectedTrack.professorData.name} + - - - - - • 연락처 - {selectedTrack.professorData.phone} - - - • 최종학력 - {selectedTrack.professorData.education} - - - • 이메일 - {selectedTrack.professorData.email} - - - • 전공분야 - {selectedTrack.professorData.major} - - - • 연구실 - {selectedTrack.professorData.location} - - - • 연구분야 - {selectedTrack.professorData.research} - - + + + 홈페이지 + + + + {selectedTrack.professorData.name} + + + + • 연락처 + {selectedTrack.professorData.phone} + + + • 최종학력 + {selectedTrack.professorData.education} + + + • 이메일 + {selectedTrack.professorData.email} + + + • 전공분야 + {selectedTrack.professorData.major} + + + • 연구실 + {selectedTrack.professorData.location} + + + • 연구분야 + {selectedTrack.professorData.research} + + + ); diff --git a/src/pages/Main/Tracks/Tracks.tsx b/src/pages/Main/Tracks/Tracks.tsx index 5d8dba7..5ca8caf 100644 --- a/src/pages/Main/Tracks/Tracks.tsx +++ b/src/pages/Main/Tracks/Tracks.tsx @@ -7,11 +7,23 @@ import OrangeArrow from '@/assets/Icons/OrangeArrow.svg'; export default function Tracks() { const [selectedTrack, setSelectedTrack] = useState(TracksData[0]); + const handleSmoothScroll = (event: React.MouseEvent, targetId: string) => { + event.preventDefault(); + const offset = 80; + const targetElement = document.querySelector(targetId); + if (targetElement) { + window.scrollTo({ + top: targetElement.getBoundingClientRect().top + window.scrollY + offset, + behavior: "smooth", + }); + } + }; + return ( 트랙 및 커리큘럼 - + handleSmoothScroll(e, "#union")}> 트랙 선택이 고민된다면 Union으로! diff --git a/src/pages/Main/Union/ContentBox.styled.ts b/src/pages/Main/Union/ContentBox.styled.ts index 421377d..c297d2f 100644 --- a/src/pages/Main/Union/ContentBox.styled.ts +++ b/src/pages/Main/Union/ContentBox.styled.ts @@ -116,9 +116,9 @@ export const Li = styled.li<{ font-size: ${(props) => props.$isMobile ? props.$isTiny - ? "18px" - : "20px" - : "24px"}; + ? "16px" + : "18px" + : "22px"}; line-height: ${(props) => (props.$isMobile ? "30px" : "35px")}; color: var(--FarmSystem_Black); diff --git a/src/pages/Main/Union/Union.tsx b/src/pages/Main/Union/Union.tsx index 755109e..d376c2e 100644 --- a/src/pages/Main/Union/Union.tsx +++ b/src/pages/Main/Union/Union.tsx @@ -6,7 +6,7 @@ export default function Union() { const { isMobile } = useMediaQueries(); return ( - +

신입생이라서

어떤 트랙을 선택할지 고민되나요?

diff --git a/src/pages/Main/index.styled.tsx b/src/pages/Main/index.styled.tsx new file mode 100644 index 0000000..b51620b --- /dev/null +++ b/src/pages/Main/index.styled.tsx @@ -0,0 +1,30 @@ +import styled from "styled-components"; + +export const MainContainer = styled.div` + position: relative; + width: 100%; + min-height: 100vh; + z-index: 2; + + &::before, &::after { + content: ""; + position: absolute; + bottom: 0; + width: 10px; + height: 40%; + background: linear-gradient(to bottom, + rgba(255, 102, 0, 0) 0%, + rgba(255, 102, 0, 0.8) 50%, + rgba(255, 102, 0, 0) 100% + ); + z-index: 3; + } + + &::before { + left: 0; + } + + &::after { + right: 0; + } +`; diff --git a/src/pages/Main/index.tsx b/src/pages/Main/index.tsx index 28232f8..1db4fc3 100644 --- a/src/pages/Main/index.tsx +++ b/src/pages/Main/index.tsx @@ -3,15 +3,18 @@ import Tracks from "./Tracks/Tracks"; import Union from "./Union/Union"; import Achievements from "./Achievements/Achievements"; import BottomInfo from "./BottomInfo/BottomInfo"; +import FarmSystemNav from "./FarmSyetemNav/FarmSystemNav"; +import * as S from "./index.styled"; export default function Main() { return ( -
+ {/* 배경 그라데이션 적용 */} + -
+ ); -} \ No newline at end of file +} diff --git a/src/styles/index.css b/src/styles/index.css index 7e11614..72e3599 100644 --- a/src/styles/index.css +++ b/src/styles/index.css @@ -8,7 +8,7 @@ body { /* 기본 색상 팔레트 */ --FarmSystem_White: #FCFCFC; --FarmSystem_Black: #191919; ---FarmSystem_LightGrey: #E5E5E5; +--FarmSystem_LightGrey: #F2F2F2; --FarmSystem_DarkGrey: #999999; --FarmSystem_Yellow: #FFF763; --FarmSystem_Orange: #FF7F1E;