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
7e62d507
Commit
7e62d507
authored
Nov 05, 2025
by
Phan Ngọc Quốc Văn
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix/home_page-and-fix/footer
parent
cbfd9322
Changes
17
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
428 additions
and
322 deletions
+428
-322
index.tsx
src/app/(main)/(home)/components/card-news/index.tsx
+11
-11
page.tsx
src/app/(main)/(home)/page.tsx
+304
-235
ScrollToTopButton.tsx
src/app/(main)/_lib/layout/ScrollToTopButton.tsx
+33
-0
footer.tsx
src/app/(main)/_lib/layout/footer.tsx
+1
-1
layout.tsx
src/app/(main)/layout.tsx
+9
-9
page.tsx
src/app/(main)/thong-tin-truyen-thong/an-pham/[id]/page.tsx
+1
-1
page.tsx
src/app/(main)/thong-tin-truyen-thong/an-pham/page.tsx
+1
-1
page.tsx
...main)/xuat-xu-hang-hoa/bieu-mau-c-o-va-cach-khai/page.tsx
+1
-1
page.tsx
...main)/xuat-xu-hang-hoa/diem-cap-va-thoi-gian-cap/page.tsx
+1
-1
page.tsx
src/app/(main)/xuat-xu-hang-hoa/luat-ap-dung/page.tsx
+1
-1
page.tsx
src/app/(main)/xuat-xu-hang-hoa/muc-dich/page.tsx
+1
-1
page.tsx
src/app/(main)/xuat-xu-hang-hoa/page.tsx
+1
-1
page.tsx
src/app/(main)/xuat-xu-hang-hoa/phi-va-le-phi-cap/page.tsx
+1
-1
page.tsx
src/app/(main)/xuat-xu-hang-hoa/thong-tin-lien-he/page.tsx
+1
-1
page.tsx
src/app/(main)/xuat-xu-hang-hoa/thu-tuc-cap/page.tsx
+1
-1
index.tsx
src/components/base/event-calendar/index.tsx
+41
-42
AppEditorContent.tsx
src/components/shared/editor-content/AppEditorContent.tsx
+19
-14
No files found.
src/app/(main)/(home)/components/card-news/index.tsx
View file @
7e62d507
import
{
NewsAdminItem
}
from
'@/api/types/news'
import
BASE_URL
from
'@/links'
import
dayjs
from
'dayjs'
;
import
AppEditorContent
from
'@/components/shared/editor-content'
;
import
{
NewsAdminItem
}
from
"@/api/types/news"
;
import
BASE_URL
from
"@/links"
;
import
dayjs
from
"dayjs"
;
import
AppEditorContent
from
"@/components/shared/editor-content"
;
function
CardNews
({
news
}:
{
news
:
NewsAdminItem
})
{
return
(
<
a
href=
{
`${news.id}`
}
className=
'flex flex-row gap-2 mb-2 sm:gap-3 sm:mb-3 p-2 sm:p-3 border border-gray-200 bg-white rounded-md'
className=
"flex flex-row gap-2 mb-2 sm:gap-3 sm:mb-3"
>
<
img
src=
{
`${BASE_URL.imageEndpoint}${news.thumbnail}`
}
alt=
{
news
.
title
}
className=
'w-[100px] md:w-[130px] aspect-3/2 object-cover'
className=
"w-[100px] md:w-[130px] aspect-3/2 object-cover"
/>
<
div
className=
'flex-1'
>
<
p
className=
'text-[#0056b3] font-bold text-sm line-clamp-2'
>
<
div
className=
"flex-1"
>
<
p
className=
"text-[#363636] font-bold text-sm line-clamp-2"
>
{
news
.
title
}
</
p
>
<
p
className=
'text-gray-500 text-sm my-1'
>
{
dayjs
(
news
.
release_at
).
format
(
'DD/MM/YYYY'
)
}
<
p
className=
"text-gray-500 text-sm my-1"
>
{
dayjs
(
news
.
release_at
).
format
(
"DD/MM/YYYY"
)
}
</
p
>
{
/* <AppEditorContent className='line-clamp-2' value={news.description} /> */
}
</
div
>
...
...
@@ -27,4 +27,4 @@ function CardNews({ news }: { news: NewsAdminItem }) {
);
}
export
default
CardNews
;
\ No newline at end of file
export
default
CardNews
;
src/app/(main)/(home)/page.tsx
View file @
7e62d507
This diff is collapsed.
Click to expand it.
src/app/(main)/_lib/layout/ScrollToTopButton.tsx
0 → 100644
View file @
7e62d507
"use client"
;
import
{
useState
,
useEffect
}
from
"react"
;
import
{
ChevronsUp
}
from
"lucide-react"
;
export
default
function
ScrollToTopButton
()
{
const
[
visible
,
setVisible
]
=
useState
(
false
);
useEffect
(()
=>
{
const
toggleVisibility
=
()
=>
{
setVisible
(
window
.
scrollY
>
300
);
};
window
.
addEventListener
(
"scroll"
,
toggleVisibility
);
return
()
=>
window
.
removeEventListener
(
"scroll"
,
toggleVisibility
);
},
[]);
const
scrollToTop
=
()
=>
{
window
.
scrollTo
({
top
:
0
,
behavior
:
"smooth"
});
};
return
(
<
button
onClick=
{
scrollToTop
}
className=
{
`fixed bottom-25 right-6 bg-[#e8c518] hover:text-[#063e8e] text-white p-3 rounded-lg shadow-lg transition-all duration-500 cursor-pointer ${
visible
? "opacity-100 translate-y-0"
: "opacity-0 translate-y-3 pointer-events-none"
}`
}
>
<
ChevronsUp
size=
{
24
}
/>
</
button
>
);
}
src/app/(main)/_lib/layout/footer.tsx
View file @
7e62d507
...
...
@@ -170,7 +170,7 @@ function footer() {
</
div
>
</
div
>
<
div
className=
"bg-[#032248] h-[80px] flex items-center justify-center"
>
<
div
className=
"
max-w-[1200px]
w-full p-5"
>
<
div
className=
"
container
w-full p-5"
>
<
p
className=
"text-[14px] text-white"
>
© Bản quyền VCCI-HCM | All rights reserved
</
p
>
...
...
src/app/(main)/layout.tsx
View file @
7e62d507
import
Header
from
"@/app/(main)/_lib/layout/header"
import
Footer
from
"@/app/(main)/_lib/layout/footer"
import
Header
from
"@/app/(main)/_lib/layout/header"
;
import
Footer
from
"@/app/(main)/_lib/layout/footer"
;
import
React
from
"react"
;
import
ScrollToTopButton
from
"./_lib/layout/ScrollToTopButton"
;
export
default
function
Layout
({
children
,
...
...
@@ -10,10 +9,11 @@ export default function Layout({
children
:
React
.
ReactNode
;
}
>
)
{
return
(
<
main
className=
"bg-background"
>
<
Header
/>
{
children
}
<
Footer
/>
</
main
>
<
main
className=
"flex flex-col min-h-screen bg-background"
>
<
Header
/>
<
div
className=
"flex-1"
>
{
children
}
</
div
>
<
ScrollToTopButton
/>
<
Footer
/>
</
main
>
);
}
src/app/(main)/thong-tin-truyen-thong/an-pham/[id]/page.tsx
View file @
7e62d507
...
...
@@ -68,7 +68,7 @@ export default function PublicationDetail() {
return
(
<
div
className=
"bg-[#f6f6f6] min-h-screen"
>
<
div
className=
"
max-w-[1200px]
mx-auto flex flex-col gap-5 mb-[50px]"
>
<
div
className=
"
container
mx-auto flex flex-col gap-5 mb-[50px]"
>
<
div
className=
"border-[#e5e7f2] border-[1px]"
>
<
ListCategory
categories=
{
MEDIA_INFORMATION_CATEGORIES
}
/>
</
div
>
...
...
src/app/(main)/thong-tin-truyen-thong/an-pham/page.tsx
View file @
7e62d507
...
...
@@ -7,7 +7,7 @@ import PublicationList from "./components/publicationList";
export
default
function
Page
()
{
return
(
<
div
className=
"bg-[#f6f6f6]"
>
<
div
className=
"
max-w-[1200px]
m-auto flex flex-col gap-5 mb-[50px]"
>
<
div
className=
"
container
m-auto flex flex-col gap-5 mb-[50px]"
>
<
div
className=
"border-[#e5e7f2] border-[1px]"
>
<
ListCategory
categories=
{
MEDIA_INFORMATION_CATEGORIES
}
/>
</
div
>
...
...
src/app/(main)/xuat-xu-hang-hoa/bieu-mau-c-o-va-cach-khai/page.tsx
View file @
7e62d507
...
...
@@ -6,7 +6,7 @@ import Calendar from "../components/Calendar";
export
default
function
page
()
{
return
(
<
div
className=
"bg-[#f6f6f6]"
>
<
div
className=
"
max-w-[1200px]
m-auto flex flex-col gap-5 mb-[50px]"
>
<
div
className=
"
container
m-auto flex flex-col gap-5 mb-[50px]"
>
<
div
className=
"border-[#e5e7f2] border-[1px]"
>
<
ListCategory
/>
</
div
>
...
...
src/app/(main)/xuat-xu-hang-hoa/diem-cap-va-thoi-gian-cap/page.tsx
View file @
7e62d507
...
...
@@ -6,7 +6,7 @@ import Calendar from "../components/Calendar";
export
default
function
page
()
{
return
(
<
div
className=
"bg-[#f6f6f6]"
>
<
div
className=
"
max-w-[1200px]
m-auto flex flex-col gap-5 mb-[50px]"
>
<
div
className=
"
container
m-auto flex flex-col gap-5 mb-[50px]"
>
<
div
className=
"border-[#e5e7f2] border-[1px]"
>
<
ListCategory
/>
</
div
>
...
...
src/app/(main)/xuat-xu-hang-hoa/luat-ap-dung/page.tsx
View file @
7e62d507
...
...
@@ -6,7 +6,7 @@ import Calendar from "../components/Calendar";
export
default
function
page
()
{
return
(
<
div
className=
"bg-[#f6f6f6]"
>
<
div
className=
"
max-w-[1200px]
m-auto flex flex-col gap-5 mb-[50px]"
>
<
div
className=
"
container
m-auto flex flex-col gap-5 mb-[50px]"
>
<
div
className=
"border-[#e5e7f2] border-[1px]"
>
<
ListCategory
/>
</
div
>
...
...
src/app/(main)/xuat-xu-hang-hoa/muc-dich/page.tsx
View file @
7e62d507
...
...
@@ -6,7 +6,7 @@ import Calendar from "../components/Calendar";
export
default
function
page
()
{
return
(
<
div
className=
"bg-[#f6f6f6]"
>
<
div
className=
"
max-w-[1200px]
m-auto flex flex-col gap-5 mb-[50px]"
>
<
div
className=
"
container
m-auto flex flex-col gap-5 mb-[50px]"
>
<
div
className=
"border-[#e5e7f2] border-[1px]"
>
<
ListCategory
/>
</
div
>
...
...
src/app/(main)/xuat-xu-hang-hoa/page.tsx
View file @
7e62d507
...
...
@@ -6,7 +6,7 @@ import Image from "next/image";
export
default
function
page
()
{
return
(
<
div
className=
"bg-[#f6f6f6]"
>
<
div
className=
"
max-w-[1200px]
m-auto flex flex-col gap-5 mb-[50px]"
>
<
div
className=
"
container
m-auto flex flex-col gap-5 mb-[50px]"
>
<
div
className=
"border-[#e5e7f2] border-[1px]"
>
<
ListCategory
/>
</
div
>
...
...
src/app/(main)/xuat-xu-hang-hoa/phi-va-le-phi-cap/page.tsx
View file @
7e62d507
...
...
@@ -6,7 +6,7 @@ import Calendar from "../components/Calendar";
export
default
function
page
()
{
return
(
<
div
className=
"bg-[#f6f6f6]"
>
<
div
className=
"
max-w-[1200px]
m-auto flex flex-col gap-5 mb-[50px]"
>
<
div
className=
"
container
m-auto flex flex-col gap-5 mb-[50px]"
>
<
div
className=
"border-[#e5e7f2] border-[1px]"
>
<
ListCategory
/>
</
div
>
...
...
src/app/(main)/xuat-xu-hang-hoa/thong-tin-lien-he/page.tsx
View file @
7e62d507
...
...
@@ -6,7 +6,7 @@ import Calendar from "../components/Calendar";
export
default
function
page
()
{
return
(
<
div
className=
"bg-[#f6f6f6]"
>
<
div
className=
"
max-w-[1200px]
m-auto flex flex-col gap-5 mb-[50px]"
>
<
div
className=
"
container
m-auto flex flex-col gap-5 mb-[50px]"
>
<
div
className=
"border-[#e5e7f2] border-[1px]"
>
<
ListCategory
/>
</
div
>
...
...
src/app/(main)/xuat-xu-hang-hoa/thu-tuc-cap/page.tsx
View file @
7e62d507
...
...
@@ -6,7 +6,7 @@ import Calendar from "../components/Calendar";
export
default
function
page
()
{
return
(
<
div
className=
"bg-[#f6f6f6]"
>
<
div
className=
"
max-w-[1200px]
m-auto flex flex-col gap-5 mb-[50px]"
>
<
div
className=
"
container
m-auto flex flex-col gap-5 mb-[50px]"
>
<
div
className=
"border-[#e5e7f2] border-[1px]"
>
<
ListCategory
/>
</
div
>
...
...
src/components/base/event-calendar/index.tsx
View file @
7e62d507
"use client"
;
import
React
,
{
useState
}
from
"react"
;
import
{
ArrowRight
,
ArrowLeft
}
from
"lucide-react"
;
export
default
function
EventCalendar
()
{
const
mockCalendar
=
{
const
mockCalendar
=
{
month
:
10
,
year
:
2025
,
highlighted
:
[
6
,
9
,
12
],
...
...
@@ -66,49 +65,49 @@ export default function EventCalendar() {
{
d
}
</
div
>
))
}
{
(()
=>
{
const
totalDays
=
new
Date
(
year
,
month
,
0
).
getDate
()
const
firstDayIndex
=
new
Date
(
year
,
month
-
1
,
1
).
getDay
()
// 0 (Sun) - 6 (Sat)
// previous month total days
const
prevMonthTotalDays
=
new
Date
(
year
,
month
-
1
,
0
).
getDate
()
const
totalCells
=
firstDayIndex
+
totalDays
const
trailingCount
=
(
7
-
(
totalCells
%
7
))
%
7
return
(
<>
{
Array
.
from
({
length
:
firstDayIndex
}).
map
((
_
,
i
)
=>
{
const
dayNum
=
prevMonthTotalDays
-
(
firstDayIndex
-
1
)
+
i
return
(
<
div
key=
{
`prev-${i}`
}
className=
"py-2 text-sm text-gray-300"
>
{
dayNum
}
</
div
>
)
})
}
{
(()
=>
{
const
totalDays
=
new
Date
(
year
,
month
,
0
).
getDate
();
const
firstDayIndex
=
new
Date
(
year
,
month
-
1
,
1
).
getDay
();
// 0 (Sun) - 6 (Sat)
// previous month total days
const
prevMonthTotalDays
=
new
Date
(
year
,
month
-
1
,
0
).
getDate
();
const
totalCells
=
firstDayIndex
+
totalDays
;
const
trailingCount
=
(
7
-
(
totalCells
%
7
))
%
7
;
{
Array
.
from
({
length
:
totalDays
},
(
_
,
i
)
=>
i
+
1
).
map
((
day
)
=>
{
const
isHighlighted
=
mockCalendar
.
highlighted
.
includes
(
day
)
return
(
<
div
key=
{
day
}
className=
{
`py-2 rounded-full w-10 h-10 flex flex-col justify-center items-center text-sm ${
isHighlighted ? 'bg-yellow-500 text-white' : 'text-gray-700'
}`
}
>
{
day
}
</
div
>
)
})
}
return
(
<>
{
Array
.
from
({
length
:
firstDayIndex
}).
map
((
_
,
i
)
=>
{
const
dayNum
=
prevMonthTotalDays
-
(
firstDayIndex
-
1
)
+
i
;
return
(
<
div
key=
{
`prev-${i}`
}
className=
"py-2 text-sm text-gray-300"
>
{
dayNum
}
</
div
>
);
})
}
{
Array
.
from
({
length
:
trailingCount
}).
map
((
_
,
i
)
=>
(
<
div
key=
{
`next-${i}`
}
className=
"py-2 text-sm text-gray-300"
>
{
i
+
1
}
{
Array
.
from
({
length
:
totalDays
},
(
_
,
i
)
=>
i
+
1
).
map
((
day
)
=>
{
const
isHighlighted
=
mockCalendar
.
highlighted
.
includes
(
day
);
return
(
<
div
key=
{
day
}
className=
{
`py-2 rounded-full w-10 h-10 flex flex-col justify-center items-center text-sm ${
isHighlighted
? "bg-yellow-500 text-white"
: "text-gray-700"
}`
}
>
{
day
}
</
div
>
))
}
</>
)
})()
}
);
})
}
{
Array
.
from
({
length
:
trailingCount
}).
map
((
_
,
i
)
=>
(
<
div
key=
{
`next-${i}`
}
className=
"py-2 text-sm text-gray-300"
>
{
i
+
1
}
</
div
>
))
}
</>
);
})()
}
</
div
>
</
div
>
);
...
...
src/components/shared/editor-content/AppEditorContent.tsx
View file @
7e62d507
import
{
FC
,
JSX
}
from
'react'
;
import
htmlParse
,
{
DOMNode
,
Element
,
Text
}
from
'html-react-parser'
;
import
{
AppEditorContentProps
}
from
'./AppEditorContent.type'
;
import
'./AppEditorContent.css'
;
import
{
FC
,
JSX
}
from
"react"
;
import
htmlParse
,
{
DOMNode
,
Element
,
Text
}
from
"html-react-parser"
;
import
{
AppEditorContentProps
}
from
"./AppEditorContent.type"
;
import
"./AppEditorContent.css"
;
const
AppEditorContent
:
FC
<
AppEditorContentProps
>
=
({
value
=
''
,
className
=
''
})
=>
{
const
AppEditorContent
:
FC
<
AppEditorContentProps
>
=
({
value
=
""
,
className
=
""
,
})
=>
{
const
transform
=
(
node
:
DOMNode
):
JSX
.
Element
|
null
=>
{
if
(
node
instanceof
Element
&&
node
.
tagName
===
'strong'
)
{
if
(
node
instanceof
Element
&&
node
.
tagName
===
"strong"
)
{
return
(
<
strong
className=
"custom-strong"
>
{
node
.
children
&&
Array
.
isArray
(
node
.
children
)
?
node
.
children
.
map
((
child
,
index
)
=>
{
if
(
typeof
child
===
'string'
)
{
return
child
;
}
else
if
(
child
instanceof
Text
)
{
return
child
.
data
;
}
return
null
;
})
if
(
typeof
child
===
"string"
)
{
return
child
;
}
else
if
(
child
instanceof
Text
)
{
return
child
.
data
;
}
return
null
;
})
:
null
}
</
strong
>
);
...
...
@@ -26,7 +29,9 @@ const AppEditorContent: FC<AppEditorContentProps> = ({ value = '', className = '
return
(
<
div
className=
"jodit-container app-editor-container"
>
<
div
className=
{
`jodit-wysiwyg ${className}`
}
>
{
htmlParse
(
value
,
{
replace
:
transform
})
}
</
div
>
<
div
className=
{
`jodit-wysiwyg ${className}`
}
>
{
htmlParse
(
value
,
{
replace
:
transform
})
}
</
div
>
</
div
>
);
};
...
...
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