Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
VCCI-News
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Văn Hoàng
VCCI-News
Commits
408059a4
Commit
408059a4
authored
Oct 31, 2025
by
Phan Ngọc Quốc Văn
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feature/add_header
parent
baecb1a1
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
239 additions
and
5 deletions
+239
-5
layout.tsx
src/app/layout.tsx
+8
-5
VCCI-HCM-logo-VN-2025.png
src/assets/VCCI-HCM-logo-VN-2025.png
+0
-0
MenuItem.tsx
src/components/ui/layout/MenuItem.tsx
+22
-0
header.tsx
src/components/ui/layout/header.tsx
+209
-0
No files found.
src/app/layout.tsx
View file @
408059a4
import
type
{
Metadata
}
from
"next"
;
import
type
{
Metadata
}
from
"next"
;
import
{
Geist
,
Geist_Mono
}
from
"next/font/google"
;
import
{
Geist
,
Geist_Mono
}
from
"next/font/google"
;
import
'./styles.css'
import
"./styles.css"
;
import
{
Providers
}
from
'./_providers'
import
{
Providers
}
from
"./_providers"
;
import
React
from
'react'
import
React
from
"react"
;
import
Header
from
"@/components/ui/layout/header"
;
const
geistSans
=
Geist
({
const
geistSans
=
Geist
({
variable
:
"--font-geist-sans"
,
variable
:
"--font-geist-sans"
,
...
@@ -24,13 +25,15 @@ export default function RootLayout({
...
@@ -24,13 +25,15 @@ export default function RootLayout({
}:
Readonly
<
{
}:
Readonly
<
{
children
:
React
.
ReactNode
;
children
:
React
.
ReactNode
;
}
>
)
{
}
>
)
{
return
(
return
(
<
html
lang=
"en"
>
<
html
lang=
"en"
>
<
body
<
body
className=
{
`${geistSans.variable} ${geistMono.variable} antialiased`
}
className=
{
`${geistSans.variable} ${geistMono.variable} antialiased`
}
>
>
<
Providers
>
{
children
}
</
Providers
>
<
Providers
>
<
Header
/>
{
children
}
</
Providers
>
</
body
>
</
body
>
</
html
>
</
html
>
);
);
...
...
src/assets/VCCI-HCM-logo-VN-2025.png
0 → 100644
View file @
408059a4
11 KB
src/components/ui/layout/MenuItem.tsx
0 → 100644
View file @
408059a4
const
MenuItem
=
({
title
,
items
}:
{
title
:
string
;
items
:
string
[]
})
=>
(
<
div
className=
"group relative"
>
<
a
className=
"px-3 py-5 text-[16px] font-[600] text-[#124588] hover:text-[#E8C518] transition block"
href=
"#"
>
{
title
}
</
a
>
<
div
className=
"absolute left-0 top-full hidden group-hover:block bg-[#124588]/98 text-white text-[14px] font-[500] min-w-[220px] shadow-lg"
>
{
items
.
map
((
item
,
i
)
=>
(
<
div
key=
{
i
}
className=
"px-5 py-3 hover:bg-[#e8c518]/80 cursor-pointer whitespace-nowrap"
>
{
item
}
</
div
>
))
}
</
div
>
</
div
>
);
export
default
MenuItem
;
src/components/ui/layout/header.tsx
0 → 100644
View file @
408059a4
"use client"
;
import
React
,
{
useState
}
from
"react"
;
import
{
Menu
,
X
,
Facebook
,
Linkedin
,
Twitter
,
Youtube
}
from
"lucide-react"
;
import
logo
from
"@/assets/VCCI-HCM-logo-VN-2025.png"
;
import
Image
from
"next/image"
;
import
MenuItem
from
"./MenuItem"
;
function
Header
()
{
const
[
toggleMenu
,
setToggleMenu
]
=
useState
<
boolean
>
(
false
);
return
(
<>
<
div
className=
"sticky top-0 w-full h-[56px] hidden lg:flex items-center justify-center bg-[#063e8e]"
>
<
div
className=
"max-w-[1215px] w-full px-4 flex items-center justify-between"
>
<
div
className=
"flex items-center gap-3"
>
<
div
className=
"w-[130px] h-[36px] bg-[#e8c518] flex items-center justify-center border-4 rounded-sm border-[#647792]"
>
<
a
className=
"font-[600] text-[14px] text-[#063E8E] hover:text-white transition"
href=
"#"
>
Đăng Ký Hội Viên
</
a
>
</
div
>
<
a
className=
"px-3 py-2 text-[14px] text-white hover:opacity-80"
href=
"#"
>
sitemap
</
a
>
<
a
className=
"px-3 py-2 text-[14px] text-white hover:opacity-80"
href=
"#"
>
Liên hệ
</
a
>
</
div
>
<
div
className=
"flex items-center gap-8"
>
<
input
className=
"bg-white h-12 rounded-sm outline-none px-4 w-64 placeholder:text-sm"
type=
"text"
placeholder=
"Tìm kiếm"
/>
<
div
className=
"flex gap-2"
>
{
[
Facebook
,
Twitter
,
Youtube
,
Linkedin
].
map
((
Icon
,
i
)
=>
(
<
a
key=
{
i
}
href=
"#"
className=
"bg-white size-7 rounded-full flex items-center justify-center text-[#063e8e] hover:opacity-80 transition"
>
<
Icon
size=
{
16
}
/>
</
a
>
))
}
</
div
>
</
div
>
</
div
>
</
div
>
<
div
className=
"sticky top-0 z-50 bg-[#ededed] shadow-md"
>
<
div
className=
"w-full flex justify-center"
>
<
div
className=
"max-w-[1200px] w-full px-4 flex items-center justify-between h-20"
>
{
/* Logo */
}
<
a
href=
"#"
className=
"flex items-center"
>
<
Image
className=
"w-[140px] object-contain lg:ml-0 ml-10"
src=
{
logo
}
alt=
"VCCI HCM"
/>
</
a
>
{
/* Desktop Menu */
}
<
nav
className=
"hidden lg:flex items-center flex-1 ml-8"
>
{
/* Dùng component MenuItem để gọn */
}
<
MenuItem
title=
"Giới thiệu"
items=
{
[
"Về VCCI-HCM"
,
"Chức Năng Và Nhiệm Vụ"
,
"Sơ Đồ Tổ Chức"
,
"Dịch Vụ Cung Cấp"
,
]
}
/>
<
MenuItem
title=
"Hội viên"
items=
{
[
"Lợi Ích Của Hội Viên VCCI"
,
"Đăng Ký Hội Viên"
,
"Kết Nối Hội Viên"
,
"Tin Hội Viên"
,
]
}
/>
<
MenuItem
title=
"Hoạt động"
items=
{
[
"Sự Kiện"
,
"Đào Tạo"
]
}
/>
<
MenuItem
title=
"Xuất Xứ Hàng Hóa"
items=
{
[
"Định Nghĩa Chung"
,
"Mục Đích Của C/O"
,
"Luật Áp Dụng Về C/O"
,
"Thủ Tục Cấp C/O"
,
"Biểu Mẫu C/O Và Cách Khai"
,
"Phí Và Lệ Phí Cấp C/O"
,
"Điểm Cấp Và Thời Gian Cấp C/O"
,
"Thông Tin Liên Hệ"
,
]
}
/>
{
/* Đại Diện Giới Chủ - có submenu cấp 2 */
}
<
div
className=
"group relative"
>
<
a
className=
"px-3 py-5 text-[16px] font-[600] text-[#124588] hover:text-[#E8C518] transition block"
href=
"#"
>
Đại Diện Giới Chủ
</
a
>
<
div
className=
"absolute left-0 top-full hidden group-hover:block bg-[#124588]/98 text-white text-[14px] font-[500] min-w-[280px] shadow-lg"
>
<
div
className=
"flex flex-col"
>
<
div
className=
"px-5 py-3 hover:bg-[#e8c518]/80 cursor-pointer"
>
Chức Năng Đại Diện Người Sử Dụng Lao Động
</
div
>
<
div
className=
"px-5 py-3 hover:bg-[#e8c518]/80 cursor-pointer"
>
Sự Kiện – Tập Huấn NSDLĐ
</
div
>
<
div
className=
"px-5 py-3 hover:bg-[#e8c518]/80 cursor-pointer"
>
Tin Liên Quan
</
div
>
<
div
className=
"relative group/submenu"
>
<
div
className=
"px-5 py-3 hover:bg-[#e8c518]/80 cursor-pointer flex justify-between items-center"
>
Chủ Đề
<
span
className=
"ml-2 text-xs"
>
›
</
span
>
</
div
>
<
div
className=
"absolute left-full top-0 hidden group-hover/submenu:block bg-[#124588]/98 text-white text-[14px] font-[500] min-w-[220px] shadow-lg"
>
<
div
className=
"px-5 py-3 hover:bg-[#e8c518]/80 cursor-pointer"
>
Quan Hệ Lao Động
</
div
>
<
div
className=
"px-5 py-3 hover:bg-[#e8c518]/80 cursor-pointer"
>
Phát Triển Kỹ Năng
</
div
>
<
div
className=
"px-5 py-3 hover:bg-[#e8c518]/80 cursor-pointer"
>
Phát Triển Bền Vững
</
div
>
</
div
>
</
div
>
</
div
>
</
div
>
</
div
>
<
MenuItem
title=
"Xúc tiến thương mại"
items=
{
[
"Hồ Sơ Thị Trường"
,
"Môi Trường Kinh Doanh"
,
"Cơ Hội Kinh Doanh"
,
"Hỗ Trợ Kinh Doanh"
,
]
}
/>
<
MenuItem
title=
"Thông tin truyền thông"
items=
{
[
"Tin VCCI"
,
"Tin Kinh Tế"
,
"Tin Doanh Nghiệp"
,
"Chuyên Đề"
,
"Thông Tin Chính Sách Và Pháp Luật"
,
"Ấn Phẩm"
,
"Thư Viện Tài Liệu"
,
]
}
/>
</
nav
>
{
/* Mobile Button */
}
<
button
onClick=
{
()
=>
setToggleMenu
((
prev
)
=>
!
prev
)
}
className=
"lg:hidden p-2 bg-[#063e8e] text-white rounded-sm"
>
{
toggleMenu
?
<
X
size=
{
20
}
/>
:
<
Menu
size=
{
20
}
/>
}
</
button
>
</
div
>
</
div
>
{
/* Mobile Menu */
}
<
div
className=
{
`lg:hidden bg-white shadow-lg transition-all duration-300 overflow-hidden ${
toggleMenu ? "max-h-96 opacity-100" : "max-h-0 opacity-0"
}`
}
>
{
[
"Giới thiệu"
,
"Hội viên"
,
"Hoạt động"
,
"Xuất Xứ Hàng Hóa"
,
"Đại Diện Giới Chủ"
,
"Xúc tiến thương mại"
,
"Thông tin truyền thông"
,
].
map
((
item
)
=>
(
<
a
key=
{
item
}
href=
"#"
className=
"block py-3 text-center hover:bg-[#124588] hover:text-white text-[16px]"
>
{
item
}
</
a
>
))
}
</
div
>
</
div
>
</>
);
}
export
default
Header
;
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment