Skip to content

Commit

Permalink
Merge pull request #31 from DguFarmSystem/fix/25-fix-header-and-union…
Browse files Browse the repository at this point in the history
…-section

Fix/25 fix header and union section
  • Loading branch information
dewbeeny authored Feb 16, 2025
2 parents 16a7342 + 08ec5fb commit d826980
Show file tree
Hide file tree
Showing 9 changed files with 239 additions and 57 deletions.
17 changes: 17 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"dev": "vite --host",
"type-check": "tsc --noEmit",
"build": "tsc -b && vite build",
"lint": "eslint .",
Expand All @@ -16,6 +16,7 @@
"framer-motion": "^12.4.3",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-icons": "^5.4.0",
"react-responsive": "^10.0.0",
"react-router": "^7.1.5",
"react-slick": "^0.30.3",
Expand Down
6 changes: 4 additions & 2 deletions src/pages/Main/FarmSyetemNav/FarmSystemNav.styled.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@ interface FixedNavProps {

export const FixedNavWrapper = styled.div<FixedNavProps>`
position: fixed;
top: ${({ isVisible }) => (isVisible ? "10px" : "-50px")};
right: 20px;
top: ${({ isVisible, $isMobile }) =>
!$isMobile ? (isVisible ? "30px" : "-50px") :(isVisible ? "20px" : "-150px")};
right: ${({ $isMobile }) => ($isMobile ? "20px" : "50px")};
transition: top 0.3s ease-in-out;
z-index: 1000;
`;


export const Navbar = styled.nav<{ $isMobile: boolean }>`
background-color: #216D35;
padding: 10px 20px;
Expand Down
60 changes: 45 additions & 15 deletions src/pages/Main/FarmSyetemNav/FarmSystemNav.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,43 @@
import * as S from './FarmSystemNav.styled';
import { useState, useEffect } from 'react';
import useMediaQueries from '@/hooks/useMediaQueries';
import MobileNav from './MobileNav';

const sectionIds = ["about", "tracks", "achievements", "eligibility"];

export default function FarmSystemNav() {
const [isVisible, setIsVisible] = useState(false);
const { isMobile } = useMediaQueries();
const [currentSection, setCurrentSection] = useState("about");

useEffect(() => {
const handleScroll = () => {
if (window.scrollY > 200) {
const scrollPosition = window.scrollY;

if (scrollPosition > 200) {
setIsVisible(true);
} else {
setIsVisible(false);
}

// 현재 섹션 확인
for (const section of sectionIds) {
const element = document.getElementById(section);
if (element) {
const offsetTop = element.offsetTop;
const offsetBottom = offsetTop + element.offsetHeight;

if (scrollPosition >= offsetTop - 100 && scrollPosition < offsetBottom - 100) {
setCurrentSection(section);
}
}
}
};


window.addEventListener("scroll", handleScroll);
handleScroll();

return () => {
window.removeEventListener("scroll", handleScroll);
};
Expand All @@ -29,25 +51,33 @@ export default function FarmSystemNav() {
top: targetElement.getBoundingClientRect().top + window.scrollY,
behavior: "smooth",
});
setCurrentSection(targetId);
}
};

return (
<S.FixedNavWrapper isVisible={isVisible} $isMobile={isMobile}>
<S.Navbar $isMobile={isMobile}>
<S.NavItem $isMobile={isMobile} href="#about" onClick={(e) => handleSmoothScroll(e, "#about")}>
<S.Circle $isMobile={isMobile} /> Farm System이란?
</S.NavItem>
<S.NavItem $isMobile={isMobile} href="#tracks" onClick={(e) => handleSmoothScroll(e, "#tracks")}>
<S.Circle $isMobile={isMobile} /> 트랙 및 커리큘럼
</S.NavItem>
<S.NavItem $isMobile={isMobile} href="#achievements" onClick={(e) => handleSmoothScroll(e, "#achievements")}>
<S.Circle $isMobile={isMobile} /> 활동 및 성과
</S.NavItem>
<S.NavItem $isMobile={isMobile} href="#eligibility" onClick={(e) => handleSmoothScroll(e, "#eligibility")}>
<S.Circle $isMobile={isMobile} /> 지원 요건
</S.NavItem>
</S.Navbar>
{isMobile ? (
<MobileNav
currentSection={currentSection}
handleSmoothScroll={handleSmoothScroll}
/>
) : (
<S.Navbar $isMobile={isMobile}>
<S.NavItem $isMobile={isMobile} href="#about" onClick={(e) => handleSmoothScroll(e, "#about")}>
<S.Circle $isMobile={isMobile} /> Farm System이란?
</S.NavItem>
<S.NavItem $isMobile={isMobile} href="#tracks" onClick={(e) => handleSmoothScroll(e, "#tracks")}>
<S.Circle $isMobile={isMobile} /> 트랙 및 커리큘럼
</S.NavItem>
<S.NavItem $isMobile={isMobile} href="#achievements" onClick={(e) => handleSmoothScroll(e, "#achievements")}>
<S.Circle $isMobile={isMobile} /> 활동 및 성과
</S.NavItem>
<S.NavItem $isMobile={isMobile} href="#eligibility" onClick={(e) => handleSmoothScroll(e, "#eligibility")}>
<S.Circle $isMobile={isMobile} /> 지원 요건
</S.NavItem>
</S.Navbar>
)}
</S.FixedNavWrapper>
);
}
52 changes: 52 additions & 0 deletions src/pages/Main/FarmSyetemNav/MobileNav.styled.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import styled from 'styled-components';

export const MobileNavbar = styled.div<{ isNavOpen: boolean }>`
max-height: ${({ isNavOpen }) => (isNavOpen ? "300px" : "80px")};
overflow: hidden;
transition: max-height 0.1s ease-in-out;
display: inline-flex;
height: auto;
padding: 10px 10px;
flex-direction: column;
justify-content: center;
align-items: center;
width: 150px;
border-radius: 20px 0px 20px 20px;
border: 1px solid var(--FarmSystem_White, #FCFCFC);
background: var(--FarmSystem_Green01, #28723F);
`;

export const MobileNavItem = styled.a`
display: flex;
padding: 5px 0px;
align-items: center;
gap: 3px;
flex: 1 0 0;
`;

export const MobileNavText = styled.p`
color: var(--FarmSystem_White, #FCFCFC);
text-align: center;
font-size: 14px;
font-style: normal;
font-weight: 500;
line-height: 16px;
letter-spacing: -0.24px;
`;

/* 확장/축소 버튼 스타일 */
export const ExpandButton = styled.button`
color: var(--FarmSystem_White, #FCFCFC);
font-size: 24px;
cursor: pointer;
width: 80%;
background-color: rgba(0, 0, 0, 0.5);
border-radius: 15px;
display: flex;
justify-content: center;
align-items: center;
`;
74 changes: 74 additions & 0 deletions src/pages/Main/FarmSyetemNav/MobileNav.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import { useState } from 'react';
import * as S from './MobileNav.styled';
import { IoMdArrowDropdown, IoMdArrowDropup } from "react-icons/io";

interface MobileNavProps {
currentSection: string;
handleSmoothScroll: (
event: React.MouseEvent<HTMLAnchorElement, MouseEvent>,
targetId: string
) => void;
}

const navItems = [
{ id: "about", text: "Farm System이란?" },
{ id: "tracks", text: "트랙 및 커리큘럼" },
{ id: "achievements", text: "활동 및 성과" },
{ id: "eligibility", text: "지원 요건" },
];

export default function MobileNav({ currentSection, handleSmoothScroll }: MobileNavProps) {
const [isNavOpen, setIsNavOpen] = useState(false);
const currentNavItem = navItems.find(item => item.id === currentSection) ?? navItems[0];

return (
<S.MobileNavbar isNavOpen={isNavOpen}>
{/*
isNavOpen이 false면 첫 번째 메뉴만 보이게,
true면 모든 메뉴가 보이게 설정
*/}
{!isNavOpen && (
<S.MobileNavItem
href={"#" + currentNavItem.id}
onClick={(e) => handleSmoothScroll(e, currentNavItem.id)}
>
<S.MobileNavText>{currentNavItem.text}</S.MobileNavText>
</S.MobileNavItem>
)}

{isNavOpen && (
<>
<S.MobileNavItem
href="#about"
onClick={(e) => handleSmoothScroll(e, "#about")}
>
<S.MobileNavText>Farm System이란?</S.MobileNavText>
</S.MobileNavItem>
<S.MobileNavItem
href="#tracks"
onClick={(e) => handleSmoothScroll(e, "#tracks")}
>
<S.MobileNavText>트랙 및 커리큘럼</S.MobileNavText>
</S.MobileNavItem>
<S.MobileNavItem
href="#achievements"
onClick={(e) => handleSmoothScroll(e, "#achievements")}
>
<S.MobileNavText>활동 및 성과</S.MobileNavText>
</S.MobileNavItem>
<S.MobileNavItem
href="#eligibility"
onClick={(e) => handleSmoothScroll(e, "#eligibility")}
>
<S.MobileNavText>지원 요건</S.MobileNavText>
</S.MobileNavItem>
</>
)}

{/* 확장/축소 버튼 */}
<S.ExpandButton onClick={() => setIsNavOpen((prev) => !prev)}>
{isNavOpen ? <IoMdArrowDropup /> : <IoMdArrowDropdown />}
</S.ExpandButton>
</S.MobileNavbar>
);
}
Loading

0 comments on commit d826980

Please sign in to comment.