메인 헤더 수정중

This commit is contained in:
wallace
2025-11-05 15:46:16 +09:00
parent bfee0c4717
commit ef82f69edc
5 changed files with 159 additions and 49 deletions

View File

@@ -3,7 +3,7 @@
* 이는 페이지 전체를 **[헤더]**, **[메인 콘텐츠]**, **[푸터]** 3개의 큰 영역으로 수직 정렬하기 위함입니다.
* `min-height: 100vh`를 설정하여 콘텐츠가 적어도 화면 전체 높이를 차지하도록 합니다.
[] 2. **헤더 (Navigation Bar) 영역**
[] 2. **헤더 (Navigation Bar) 영역**
* `display: flex`, `flex-direction: row`, `justify-content: space-between`을 사용하여 **로고/메뉴 그룹**과 **사용자 메뉴(내 강의실, 프로필) 그룹**을 양쪽 끝으로 배치합니다.
* 로고/메뉴 그룹 내부도 `display: flex`, `align-items: center`로 로고와 메뉴 항목들을 정렬합니다.
* **[반응형]** 모바일 화면(@media 쿼리 사용)에서는 메뉴 항목들을 숨기고 햄버거 메뉴 아이콘을 표시하도록 처리합니다.

View File

@@ -1,36 +1,149 @@
"use client";
import Link from "next/link";
import { useState } from "react";
const logoImage = "http://localhost:3845/assets/89fda8e949171025b1232bae70fc9d442e4e70c8.png";
const chevronIcon = "http://localhost:3845/assets/6abc26b721560f9d3c51cf552531775f54f2f86a.svg";
export default function Home() {
const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
const [isUserMenuOpen, setIsUserMenuOpen] = useState(false);
return (
<div className="flex flex-col flex-1 bg-white">
{/* 헤더 */}
<header className="bg-white shadow-sm sticky top-0 z-50">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="flex justify-between items-center h-16">
<div className="flex items-center">
<h1 className="text-2xl font-bold text-blue-600">XR LMS</h1>
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-16">
<div className="flex flex-row justify-between items-center gap-4 py-6">
{/* 로고/메뉴 그룹 */}
<div className="flex items-center gap-9 flex-1">
{/* Company 로고 */}
<div className="flex items-center gap-2">
<div className="h-9 relative w-[46.703px]">
<img
alt="XR LMS Logo"
className="h-full w-full object-contain"
src={logoImage}
/>
</div>
<h1 className="text-2xl font-bold text-black leading-[1.45] whitespace-pre">XR LMS</h1>
</div>
{/* 네비게이션 메뉴 */}
<nav className="hidden md:flex items-center">
<div className="flex gap-0.5">
<Link href="#" className="px-4 py-2 text-[#111111] font-bold text-base hover:text-blue-600 transition">
</Link>
<Link href="#" className="px-4 py-2 text-[#111111] font-bold text-base hover:text-blue-600 transition">
</Link>
<Link href="#" className="px-4 py-2 text-[#111111] font-bold text-base hover:text-blue-600 transition">
</Link>
<Link href="#" className="px-4 py-2 text-[#111111] font-bold text-base hover:text-blue-600 transition">
</Link>
<Link href="#" className="px-4 py-2 text-[#111111] font-bold text-base hover:text-blue-600 transition">
</Link>
</div>
</nav>
</div>
<nav className="hidden md:flex space-x-8">
<Link href="#" className="text-gray-700 hover:text-blue-600 transition"></Link>
<Link href="#" className="text-gray-700 hover:text-blue-600 transition"></Link>
<Link href="#" className="text-gray-700 hover:text-blue-600 transition"></Link>
<Link href="#" className="text-gray-700 hover:text-blue-600 transition"></Link>
{/* 사용자 메뉴 그룹 */}
<nav className="flex items-center gap-6 shrink-0">
<div className="hidden md:flex items-center gap-6">
<Link
href="#"
className="px-4 py-2 text-[#5f5f5f] font-bold text-base hover:text-blue-600 transition h-9 flex items-center"
>
</Link>
<div className="relative">
<button
onClick={() => setIsUserMenuOpen(!isUserMenuOpen)}
className="flex items-center gap-1 px-4 py-2 text-[#5f5f5f] font-bold text-base hover:text-blue-600 transition h-9"
>
<span></span>
<div className="rotate-180">
<img
src={chevronIcon}
alt="chevron"
className="w-6 h-6"
/>
</div>
</button>
{/* 사용자 메뉴 드롭다운 */}
{isUserMenuOpen && (
<div className="absolute right-0 mt-2 bg-white border border-gray-200 rounded-md shadow-lg py-2 min-w-[120px]">
<Link href="#" className="block px-4 py-2 text-gray-700 hover:bg-gray-100"></Link>
<Link href="#" className="block px-4 py-2 text-gray-700 hover:bg-gray-100"></Link>
<Link href="#" className="block px-4 py-2 text-gray-700 hover:bg-gray-100"></Link>
</div>
)}
</div>
</div>
{/* 모바일 햄버거 메뉴 아이콘 */}
<button
className="md:hidden p-2 text-gray-700 hover:text-blue-600 transition"
onClick={() => setIsMobileMenuOpen(!isMobileMenuOpen)}
aria-label="메뉴"
>
<svg
className="w-6 h-6"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
{isMobileMenuOpen ? (
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M6 18L18 6M6 6l12 12"
/>
) : (
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M4 6h16M4 12h16M4 18h16"
/>
)}
</svg>
</button>
</nav>
<div className="flex items-center space-x-4">
<Link
href="/registeragreement"
className="px-4 py-2 text-gray-700 hover:text-blue-600 transition"
>
</Link>
<Link
href="/login"
className="px-4 py-2 bg-blue-500 text-white rounded-md hover:bg-blue-600 transition"
>
</Link>
</div>
</div>
{/* 모바일 메뉴 */}
{isMobileMenuOpen && (
<div className="md:hidden border-t border-gray-200 py-4">
<nav className="flex flex-col space-y-4">
<Link href="#" className="text-gray-700 hover:text-blue-600 transition px-2 font-bold"> </Link>
<Link href="#" className="text-gray-700 hover:text-blue-600 transition px-2 font-bold"> </Link>
<Link href="#" className="text-gray-700 hover:text-blue-600 transition px-2 font-bold"></Link>
<Link href="#" className="text-gray-700 hover:text-blue-600 transition px-2 font-bold"></Link>
<Link href="#" className="text-gray-700 hover:text-blue-600 transition px-2 font-bold"></Link>
<div className="pt-4 border-t border-gray-200 flex flex-col space-y-2">
<Link
href="#"
className="px-4 py-2 text-gray-700 hover:text-blue-600 transition font-bold"
>
</Link>
<Link
href="#"
className="px-4 py-2 text-gray-700 hover:text-blue-600 transition font-bold"
>
</Link>
</div>
</nav>
</div>
)}
</div>
</header>

17
package-lock.json generated
View File

@@ -14,13 +14,13 @@
},
"devDependencies": {
"@tailwindcss/postcss": "^4",
"@types/node": "^20",
"@types/react": "^19",
"@types/node": "20.19.24",
"@types/react": "19.2.2",
"@types/react-dom": "^19",
"eslint": "^9",
"eslint-config-next": "16.0.1",
"tailwindcss": "^4",
"typescript": "^5"
"typescript": "5.9.3"
}
},
"node_modules/@alloc/quick-lru": {
@@ -67,7 +67,6 @@
"integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@babel/code-frame": "^7.27.1",
"@babel/generator": "^7.28.5",
@@ -1524,7 +1523,6 @@
"integrity": "sha512-6mDvHUFSjyT2B2yeNx2nUgMxh9LtOWvkhIU3uePn2I2oyNymUAX1NIsdgviM4CH+JSrp2D2hsMvJOkxY+0wNRA==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"csstype": "^3.0.2"
}
@@ -1585,7 +1583,6 @@
"integrity": "sha512-BnOroVl1SgrPLywqxyqdJ4l3S2MsKVLDVxZvjI1Eoe8ev2r3kGDo+PcMihNmDE+6/KjkTubSJnmqGZZjQSBq/g==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@typescript-eslint/scope-manager": "8.46.2",
"@typescript-eslint/types": "8.46.2",
@@ -2116,7 +2113,6 @@
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
"dev": true,
"license": "MIT",
"peer": true,
"bin": {
"acorn": "bin/acorn"
},
@@ -2458,7 +2454,6 @@
}
],
"license": "MIT",
"peer": true,
"dependencies": {
"baseline-browser-mapping": "^2.8.19",
"caniuse-lite": "^1.0.30001751",
@@ -3026,7 +3021,6 @@
"integrity": "sha512-t5aPOpmtJcZcz5UJyY2GbvpDlsK5E8JqRqoKtfiKE3cNh437KIqfJr3A3AKf5k64NPx6d0G3dno6XDY05PqPtw==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.8.0",
"@eslint-community/regexpp": "^4.12.1",
@@ -5390,7 +5384,6 @@
"resolved": "https://registry.npmjs.org/react/-/react-19.2.0.tgz",
"integrity": "sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ==",
"license": "MIT",
"peer": true,
"engines": {
"node": ">=0.10.0"
}
@@ -5400,7 +5393,6 @@
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.0.tgz",
"integrity": "sha512-UlbRu4cAiGaIewkPyiRGJk0imDN2T3JjieT6spoL2UeSf5od4n5LB/mQ4ejmxhCFT1tYe8IvaFulzynWovsEFQ==",
"license": "MIT",
"peer": true,
"dependencies": {
"scheduler": "^0.27.0"
},
@@ -6087,7 +6079,6 @@
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
"dev": true,
"license": "MIT",
"peer": true,
"engines": {
"node": ">=12"
},
@@ -6250,7 +6241,6 @@
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
"dev": true,
"license": "Apache-2.0",
"peer": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
@@ -6526,7 +6516,6 @@
"integrity": "sha512-JInaHOamG8pt5+Ey8kGmdcAcg3OL9reK8ltczgHTAwNhMys/6ThXHityHxVV2p3fkw/c+MAvBHFVYHFZDmjMCQ==",
"dev": true,
"license": "MIT",
"peer": true,
"funding": {
"url": "https://github.com/sponsors/colinhacks"
}

View File

@@ -9,18 +9,18 @@
"lint": "eslint"
},
"dependencies": {
"next": "16.0.1",
"react": "19.2.0",
"react-dom": "19.2.0",
"next": "16.0.1"
"react-dom": "19.2.0"
},
"devDependencies": {
"typescript": "^5",
"@types/node": "^20",
"@types/react": "^19",
"@types/react-dom": "^19",
"@tailwindcss/postcss": "^4",
"tailwindcss": "^4",
"@types/node": "20.19.24",
"@types/react": "19.2.2",
"@types/react-dom": "^19",
"eslint": "^9",
"eslint-config-next": "16.0.1"
"eslint-config-next": "16.0.1",
"tailwindcss": "^4",
"typescript": "5.9.3"
}
}

View File

@@ -1,7 +1,11 @@
{
"compilerOptions": {
"target": "ES2017",
"lib": ["dom", "dom.iterable", "esnext"],
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
@@ -19,7 +23,9 @@
}
],
"paths": {
"@/*": ["./*"]
"@/*": [
"./*"
]
}
},
"include": [
@@ -30,5 +36,7 @@
".next/dev/types/**/*.ts",
"**/*.mts"
],
"exclude": ["node_modules"]
"exclude": [
"node_modules"
]
}