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
c2d14537
Commit
c2d14537
authored
Nov 04, 2025
by
Phạm Quang Bảo
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
update/layout page
parent
4d628084
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
154 additions
and
114 deletions
+154
-114
page.tsx
src/app/(main)/(home)/[id]/page.tsx
+23
-68
index.tsx
src/app/(main)/(home)/components/card-news/index.tsx
+2
-2
page.tsx
src/app/(main)/(home)/page.tsx
+124
-38
index.tsx
src/components/base/card-news/index.tsx
+5
-6
No files found.
src/app/(main)/(home)/[id]/page.tsx
View file @
c2d14537
...
...
@@ -12,6 +12,9 @@ import { GetNewsDetailResponseType } from './page.type';
import
{
Link
,
CalendarFold
,
Book
}
from
'lucide-react'
;
import
{
useEffect
,
useMemo
}
from
'react'
;
import
{
useParams
}
from
'next/navigation'
import
ListCategory
from
'@/components/base/list-category'
import
{
MEDIA_INFORMATION_CATEGORIES
}
from
'@/constants/categories'
import
EventCalendar
from
'@/components/base/event-calendar'
// import { t } from 'i18next'
// Component
...
...
@@ -33,82 +36,34 @@ const NewsDetailPage = () => {
<
Spinner
/>
)
:
(
<
div
>
{
/* Banner */
}
<
img
className=
'w-full h-100'
src=
{
`${BASE_URLS.imageEndpoint}${data?.responseData?.thumbnail}`
}
alt=
'Banner'
/>
{
/* Breadcrumb */
}
<
div
className=
'container py-10'
>
<
div
className=
'flex gap-4 items-stretch'
>
{
/* <Breadcrumbs aria-label='breadcrumb'>
<Link
underline='hover'
color='inherit'
href='/'
className='!text-app-blue-secondary !text-sm !leading-normal'
>
{t('breadcrumbHomePage')}
<p>Trang chủ</p>
</Link>
<Link
underline='hover'
color='inherit'
href='/tin-tuc'
className='!text-app-blue-secondary !text-sm !leading-normal'
>
{t('breadcrumbNewsPage')}
<p>Tin tức</p>
</Link>
<Typography className='!text-sm !text-black !leading-normal'>
{t('breadcrumbNewsDetailPage')}
<p>Chi tiết</p>
</Typography>
</Breadcrumbs> */
}
</
div
>
</
div
>
<
div
className=
'container bg-gray-100 rounded p-10 flex flex-col gap-10'
>
{
/* Heading */
}
<
div
className=
'text-blue-900 text-[32px] leading-normal font-medium text-center'
>
{
data
?.
responseData
?.
title
}
</
div
>
{
/* body */
}
<
div
className=
'flex items-start gap-8 flex-col lg:flex-row'
>
{
/* Info */
}
<
div
className=
'lg:w-[332px] bg-white p-4 rounded shadow-app-quaternary flex flex-col gap-2'
>
<
div
className=
'text-base text-app-grey font-semibold leading-normal text-center'
>
{
/* {t('information')} */
}
<
div
className=
'container flex flex-col gap-5'
>
<
ListCategory
categories=
{
MEDIA_INFORMATION_CATEGORIES
}
/>
<
div
className=
"grid grid-cols-1 lg:grid-cols-3 gap-5"
>
{
/* Main content */
}
<
main
className=
"lg:col-span-2 bg-white border rounded-md p-7"
>
<
div
className=
'pb-5 text-blue-900 text-2xl leading-normal font-medium'
>
{
data
?.
responseData
?.
title
}
</
div
>
{
/* date */
}
<
div
className=
'flex items-center gap-2 text-app-grey'
>
<
div
className=
'flex items-center gap-2 text-sm mb-4'
>
<
CalendarFold
/>
<
span
className=
'text-base'
>
{
dayjs
(
data
?.
responseData
?.
created_at
).
format
(
'DD/MM/YYYY'
)
}
</
span
>
</
div
>
{
/* author */
}
{
/* <div className='flex items-center gap-2 text-app-grey'>
<PersonIcon />
<span className='text-base'>{data?.responseData?.created_by}</span>
</div> */
}
{
/* Category */
}
<
div
className=
'flex items-center gap-2 text-app-grey'
>
<
Book
/>
<
span
className=
'text-base'
>
{
data
?.
responseData
?.
category
}
</
span
>
<
span
className=
'text-base text-blue-700'
>
{
dayjs
(
data
?.
responseData
?.
created_at
).
format
(
'DD/MM/YYYY'
)
}
</
span
>
</
div
>
<
div
className=
'py-5'
>
<
hr
/>
</
div
>
{
/* Content */
}
<
div
className=
'flex-1 text-app-grey text-base overflow-hidden'
>
<
AppEditorContent
value=
{
data
?.
responseData
?.
description
??
''
}
/>
</
div
>
</
main
>
{
/* Sidebar */
}
<
aside
className=
"space-y-6"
>
<
EventCalendar
/>
</
aside
>
</
div
>
</
div
>
{
/* Related News */
}
{
/* <RelatedNews newsQuery={getRelatedNewsQuery} lang={lang} newsId={infoNews.id} /> */
}
</
div
>
)
}
</
div
>
</
div
>
)
}
...
...
src/app/(main)/(home)/components/card-news/index.tsx
View file @
c2d14537
...
...
@@ -7,12 +7,12 @@ function CardNews({ news }: { news: NewsAdminItem }) {
return
(
<
a
href=
{
`${news.id}`
}
className=
'flex flex-row gap-
3 mb-3 border border-gray-200 bg-white rounded-md p-3
'
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
'
>
<
img
src=
{
`${BASE_URL.imageEndpoint}${news.thumbnail}`
}
alt=
{
news
.
title
}
className=
'w-[1
20px] h-20 object-cover rounded-sm
'
className=
'w-[1
00px] md:w-[130px] aspect-3/2 object-cover
'
/>
<
div
className=
'flex-1'
>
<
p
className=
'text-[#0056b3] font-bold text-sm line-clamp-2'
>
...
...
src/app/(main)/(home)/page.tsx
View file @
c2d14537
...
...
@@ -14,8 +14,10 @@ import { Spinner } from '@/components/ui'
import
{
useGetCategory
}
from
'@/api/endpoints/category'
import
{
useGetNews
}
from
'@/api/endpoints/news'
import
{
GetCategoryAdminResponseType
}
from
'@/api/types/category'
import
{
GetNewsAdminResponseType
}
from
'@/api/types/news'
import
{
GetNewsAdminResponseType
,
NewsAdminItem
}
from
'@/api/types/news'
import
EventCalendar
from
'./components/event-calendar'
import
dayjs
from
'dayjs'
import
AppEditorContent
from
'@/components/shared/editor-content'
const
Page
=
()
=>
{
const
[
tab
,
setTab
]
=
useState
(
'all'
)
...
...
@@ -136,13 +138,13 @@ const Page = () => {
{
rows
.
map
((
news
)
=>
(
<
SwiperSlide
key=
{
news
.
id
}
>
<
a
href=
{
`/
tin-tuc/
${news.id}`
}
href=
{
`/${news.id}`
}
className=
"relative block bg-white rounded-xl shadow-md overflow-hidden hover:shadow-lg transition-shadow duration-300"
>
<
img
src=
{
`${BASE_URL.imageEndpoint}${news.thumbnail}`
}
alt=
{
news
.
title
}
className=
"w-full
h-48
sm:h-56 md:h-64 object-cover"
className=
"w-full
aspect-3/2
sm:h-56 md:h-64 object-cover"
/>
<
div
className=
"absolute bottom-0 left-0 right-0 h-20 md:h-24 bg-linear-to-t from-black/80 to-transparent flex items-center justify-center p-3"
>
<
p
className=
"text-white text-center font-semibold line-clamp-2 text-sm sm:text-base leading-snug"
>
...
...
@@ -166,19 +168,41 @@ const Page = () => {
{
/* Left */
}
<
div
className=
"flex-1"
>
<
div
className=
"flex justify-between items-center"
>
<
h2
className=
"text-[18px] sm:text-[20px] font-bold uppercase text-blue-900"
>
<
a
href=
"/thong-tin-truyen-thong/tin-vcci/"
className=
"text-[18px] sm:text-[20px] font-bold uppercase text-blue-900"
>
Tin tức
</
h2
>
<
a
href=
"
#"
className=
"text-blue-900 hover:underline
text-sm sm:text-base"
>
</
a
>
<
a
href=
"
/thong-tin-truyen-thong/tin-vcci/"
className=
"text-blue-900
text-sm sm:text-base"
>
{
'>>'
}
</
a
>
</
div
>
<
hr
className=
"border-blue-900 mb-4"
/>
<
div
className=
"flex flex-col md:flex-row gap-5"
>
<
div
className=
"w-full md:w-1/2 bg-gray-500 flex items-center justify-center rounded-lg p-4 min-h-[180px] sm:min-h-[220px]"
>
<
p
className=
"text-white text-center"
>
Khung tin tức VIP
</
p
>
{
allData
?.
responseData
.
rows
.
slice
(
0
,
1
).
map
((
news
:
NewsAdminItem
)
=>
(
<
a
key=
{
news
.
id
}
href=
{
`${news.id}`
}
className=
"flex flex-col w-full md:w-1/2 min-h-[180px] sm:min-h-[220px] gap-3 mb-3 border border-gray-200 bg-white rounded-md p-3"
>
<
div
className=
"w-full aspect-3/2 overflow-hidden"
>
<
img
src=
{
`${BASE_URL.imageEndpoint}${news.thumbnail}`
}
alt=
{
news
.
title
}
className=
"w-full h-full object-cover"
/>
</
div
>
<
div
className=
"flex-1"
>
<
p
className=
"text-[#0056b3] font-bold text-xl line-clamp-2"
>
{
news
.
title
}
</
p
>
<
p
className=
"text-gray-500 text-sm my-1"
>
{
dayjs
(
news
.
release_at
).
format
(
'DD/MM/YYYY'
)
}
</
p
>
<
AppEditorContent
className=
"line-clamp-4"
value=
{
news
.
description
}
/>
</
div
>
</
a
>
))
}
<
div
className=
"w-full md:w-1/2"
>
<
div
className=
"flex flex-wrap gap-2 sm:gap-3 mb-3"
>
...
...
@@ -205,7 +229,7 @@ const Page = () => {
))
}
</
div
>
{
filteredRows
.
slice
(
0
,
5
).
map
((
news
)
=>
(
{
filteredRows
.
slice
(
0
,
4
).
map
((
news
)
=>
(
<
NewsContent
key=
{
news
.
id
}
news=
{
news
}
/>
))
}
</
div
>
...
...
@@ -257,11 +281,33 @@ const Page = () => {
<
hr
className=
"border-[#e8c518] mb-4"
/>
<
div
className=
"flex flex-col md:flex-row gap-5"
>
<
div
className=
"w-full md:w-1/2 bg-gray-500 flex items-center justify-center rounded-lg p-4 min-h-[180px] sm:min-h-[220px]"
>
<
p
className=
"text-white"
>
Khung tin tức VIP
</
p
>
{
allData
?.
responseData
.
rows
.
slice
(
0
,
1
).
map
((
news
:
NewsAdminItem
)
=>
(
<
a
key=
{
news
.
id
}
href=
{
`${news.id}`
}
className=
"flex flex-col w-full md:w-1/2 min-h-[180px] sm:min-h-[220px] gap-3 mb-3 border border-gray-200 bg-white rounded-md p-3"
>
<
div
className=
"w-full aspect-3/2 overflow-hidden"
>
<
img
src=
{
`${BASE_URL.imageEndpoint}${news.thumbnail}`
}
alt=
{
news
.
title
}
className=
"w-full h-full object-cover"
/>
</
div
>
<
div
className=
"flex-1"
>
<
p
className=
"text-[#0056b3] font-bold text-xl line-clamp-2"
>
{
news
.
title
}
</
p
>
<
p
className=
"text-gray-500 text-sm my-1"
>
{
dayjs
(
news
.
release_at
).
format
(
'DD/MM/YYYY'
)
}
</
p
>
<
AppEditorContent
className=
"line-clamp-3"
value=
{
news
.
description
}
/>
</
div
>
</
a
>
))
}
<
div
className=
"w-full md:w-1/2"
>
{
rows
.
slice
(
0
,
5
).
map
((
news
)
=>
(
{
rows
.
slice
(
0
,
4
).
map
((
news
)
=>
(
<
NewsContent
key=
{
news
.
id
}
news=
{
news
}
/>
))
}
</
div
>
...
...
@@ -294,32 +340,72 @@ const Page = () => {
<
section
className=
"flex flex-col md:flex-row gap-5 pt-8"
>
<
div
className=
"flex-1"
>
<
div
className=
"flex justify-between items-center"
>
<
h2
className=
"text-[18px] sm:text-[20px] font-bold uppercase text-blue-900"
>
<
a
href=
"/xuc-tien-thuong-mai/co-hoi-kinh-doanh/"
className=
"text-[18px] sm:text-[20px] font-bold uppercase text-blue-900"
>
Cơ hội kinh doanh
</
h2
>
<
a
href=
"
#
"
className=
"text-blue-900 text-sm sm:text-base"
>
</
a
>
<
a
href=
"
/xuc-tien-thuong-mai/co-hoi-kinh-doanh/
"
className=
"text-blue-900 text-sm sm:text-base"
>
{
'>>'
}
</
a
>
</
div
>
<
hr
className=
"border-blue-900 mb-4"
/>
<
div
className=
"pt-2 space-y-3"
>
{
rows
.
slice
(
0
,
4
).
map
((
news
)
=>
(
<
div
className=
"pt-2"
>
{
allData
?.
responseData
.
rows
.
slice
(
0
,
1
).
map
((
news
:
NewsAdminItem
)
=>
(
<
a
key=
{
news
.
id
}
href=
{
`${news.id}`
}
>
<
div
className=
"w-full aspect-3/2 relative overflow-hidden mb-5"
>
<
img
src=
{
`${BASE_URL.imageEndpoint}${news.thumbnail}`
}
alt=
{
news
.
title
}
className=
"w-full h-full object-cover"
/>
<
div
className=
"absolute bg-white opacity-80 bottom-5 left-5 right-5 p-5"
>
<
p
className=
"text-blue-900 font-semibold text-sm sm:text-base z-10 line-clamp-3"
>
{
news
.
title
}
</
p
>
</
div
>
</
div
>
</
a
>
))
}
{
rows
.
slice
(
0
,
3
).
map
((
news
)
=>
(
<
NewsContent
key=
{
news
.
id
}
news=
{
news
}
/>
))
}
</
div
>
</
div
>
<
div
className=
"flex-1"
>
<
div
className=
"flex justify-between items-center"
>
<
h2
className=
"text-[18px] sm:text-[20px] font-bold uppercase text-blue-900"
>
<
a
href=
"/thong-tin-truyen-thong/thong-tin-chinh-sach-va-phap-luat"
className=
"text-[18px] sm:text-[20px] font-bold uppercase text-blue-900"
>
Chính sách
&
pháp luật
</
h2
>
<
a
href=
"
#
"
className=
"text-blue-900 text-sm sm:text-base"
>
</
a
>
<
a
href=
"
/thong-tin-truyen-thong/thong-tin-chinh-sach-va-phap-luat
"
className=
"text-blue-900 text-sm sm:text-base"
>
{
'>>'
}
</
a
>
</
div
>
<
hr
className=
"border-blue-900 mb-4"
/>
<
div
className=
"pt-2 space-y-3"
>
{
rows
.
slice
(
0
,
4
).
map
((
news
)
=>
(
<
div
className=
"pt-2"
>
{
allData
?.
responseData
.
rows
.
slice
(
0
,
1
).
map
((
news
:
NewsAdminItem
)
=>
(
<
a
key=
{
news
.
id
}
href=
{
`${news.id}`
}
>
<
div
className=
"w-full aspect-3/2 relative overflow-hidden mb-5"
>
<
img
src=
{
`${BASE_URL.imageEndpoint}${news.thumbnail}`
}
alt=
{
news
.
title
}
className=
"w-full h-full object-cover"
/>
<
div
className=
"absolute bg-white opacity-80 bottom-5 left-5 right-5 p-5"
>
<
p
className=
"text-blue-900 font-semibold text-sm sm:text-base z-10 line-clamp-3"
>
{
news
.
title
}
</
p
>
</
div
>
</
div
>
</
a
>
))
}
{
rows
.
slice
(
0
,
3
).
map
((
news
)
=>
(
<
NewsContent
key=
{
news
.
id
}
news=
{
news
}
/>
))
}
</
div
>
...
...
@@ -331,12 +417,12 @@ const Page = () => {
<
img
src=
"/home/eCarAid_web_banner_600x400.webp"
alt=
"banner"
/>
</
a
>
</
div
>
</
div
>
</
div
>
{
/* Hội viên tiêu biểu */
}
<
section
className=
"flex flex-col lg:flex-row gap-5 pb-10 mb-0"
>
<
section
className=
"flex flex-col lg:flex-row gap-5 pb-10 mb-0"
>
{
/* left */
}
<
aside
className=
"w-full lg:w-1/3 flex-1 bg-[#e8c518] p-5"
>
<
aside
className=
"w-full lg:w-1/3 flex-1 bg-[#e8c518] p-5"
>
<
div
className=
"flex justify-between items-center mb-3"
>
<
h2
className=
"text-xl font-bold uppercase text-blue-900"
>
Hội viên tiêu biểu
</
h2
>
<
a
...
...
@@ -374,10 +460,10 @@ const Page = () => {
))
}
</
Swiper
>
</
div
>
</
aside
>
</
aside
>
{
/* right */
}
<
aside
className=
"w-full lg:w-[30%] py-5"
>
<
aside
className=
"w-full lg:w-[30%] py-5"
>
<
div
className=
"flex justify-between items-center mb-3"
>
<
h2
className=
"text-xl font-bold uppercase text-blue-900"
>
Kết nối hội viên
</
h2
>
<
a
...
...
@@ -415,13 +501,13 @@ const Page = () => {
))
}
</
Swiper
>
</
div
>
</
aside
>
</
section
>
</
aside
>
</
section
>
{
/* Video + đối tác */
}
<
section
className=
"flex flex-col lg:flex-row gap-5 pb-10"
>
<
section
className=
"flex flex-col lg:flex-row gap-5 pb-10"
>
{
/* left */
}
<
div
className=
"flex flex-col flex-1"
>
<
div
className=
"flex flex-col flex-1"
>
<
div
className=
"flex justify-between items-center mb-3"
>
<
h2
className=
"text-xl font-bold uppercase text-blue-900"
>
Video
</
h2
>
<
a
...
...
@@ -459,10 +545,10 @@ const Page = () => {
</
div
>
))
}
</
div
>
</
div
>
</
div
>
{
/* right */
}
<
aside
className=
"w-full lg:w-[30%]"
>
<
aside
className=
"w-full lg:w-[30%]"
>
<
div
className=
"flex justify-between items-center mb-3"
>
<
h2
className=
"text-xl font-bold uppercase text-blue-900"
>
Đối tác
</
h2
>
<
a
...
...
@@ -500,9 +586,9 @@ const Page = () => {
))
}
</
Swiper
>
</
div
>
</
aside
>
</
section
>
</
div
>
</
aside
>
</
section
>
</
div
>
</>
)
}
...
...
src/components/base/card-news/index.tsx
View file @
c2d14537
...
...
@@ -3,7 +3,7 @@ import { NewsItem } from '@app/dai-dien-gioi-chu/lib/types/NewsPage.type';
import
Links
from
'@links/index'
import
dayjs
from
'dayjs'
;
import
parse
from
'html-react-parser'
function
NewsContent
({
news
,
link
}:
{
news
:
NewsItem
,
link
:
string
})
{
function
NewsContent
({
news
,
link
}:
{
news
:
NewsItem
,
link
:
string
})
{
return
(
<
a
...
...
@@ -17,11 +17,10 @@ function NewsContent({ news ,link}: { news: NewsItem ,link:string}) {
onError=
{
(
e
)
=>
{
e
.
currentTarget
.
src
=
"/img-error.png"
}
}
/>
<
div
className=
"flex-1 min-w-0 pl-0 sm:pl-4"
>
<
p
className=
"text-primary font-semibold text-base md:text-lg
hover:underline
line-clamp-2 wrap-break-word hover:no-underline"
>
<
p
className=
"text-primary font-semibold text-base md:text-lg line-clamp-2 wrap-break-word hover:no-underline"
>
{
news
.
title
}
</
p
>
...
...
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