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
227363b8
Commit
227363b8
authored
Nov 04, 2025
by
Vũ Đình Nguyên
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'feat/home_page' into 'develop'
Feat/home page See merge request
!8
parents
4d628084
e83b5a22
Changes
6
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
275 additions
and
142 deletions
+275
-142
event.ts
src/api/types/event.ts
+74
-0
page.tsx
src/app/(main)/(home)/[id]/page.tsx
+23
-68
index.tsx
src/app/(main)/(home)/components/card-event/index.tsx
+30
-0
index.tsx
src/app/(main)/(home)/components/card-news/index.tsx
+2
-2
page.tsx
src/app/(main)/(home)/page.tsx
+141
-66
index.tsx
src/components/base/card-news/index.tsx
+5
-6
No files found.
src/api/types/event.ts
0 → 100644
View file @
227363b8
export
type
EventStatus
=
{
id
:
string
;
name
:
string
;
name_en
:
string
;
code
:
string
;
};
export
type
EventOrganization
=
{
id
:
string
;
organization_id
:
string
|
null
;
event_id
:
string
;
status
:
string
|
null
;
created_at
:
string
;
updated_at
:
string
|
null
;
created_by
:
string
;
updated_by
:
string
|
null
;
role
:
string
;
guest_name
:
string
;
guest_image
:
string
;
org_table_count
:
number
|
null
;
org_counter_count
:
number
|
null
;
add_info
:
unknown
|
null
;
organization
:
unknown
|
null
;
};
export
type
EventItem
=
{
id
:
string
;
name
:
string
;
start_time
:
string
;
end_time
:
string
;
created_at
:
string
;
created_by
:
string
;
updated_at
:
string
|
null
;
updated_by
:
string
|
null
;
status
:
string
;
image
:
string
;
description
:
string
;
location
:
string
;
province
:
string
;
table_count
:
number
;
counter_count
:
number
;
seo_text
:
string
;
seo_text_en
:
string
|
null
;
table_cost
:
number
;
counter_cost
:
number
;
table_min_pick
:
number
|
null
;
counter_min_pick
:
number
|
null
;
table_max_pick
:
number
|
null
;
counter_max_pick
:
number
|
null
;
org_support_titles
:
string
[];
accept_entries
:
boolean
;
type
:
string
;
introduction
:
string
;
host_club
:
string
|
null
;
config
:
unknown
|
null
;
event_organizations
:
EventOrganization
[];
status_status
:
EventStatus
;
};
export
type
EventResponseData
=
{
count
:
number
;
rows
:
EventItem
[];
totalPages
:
number
;
currentPage
:
number
;
};
export
type
EventApiResponse
=
{
message
:
string
;
message_en
:
string
;
responseData
:
EventResponseData
;
status
:
string
;
timeStamp
:
string
;
violations
:
null
|
unknown
;
};
\ No newline at end of file
src/app/(main)/(home)/[id]/page.tsx
View file @
227363b8
...
@@ -12,6 +12,9 @@ import { GetNewsDetailResponseType } from './page.type';
...
@@ -12,6 +12,9 @@ import { GetNewsDetailResponseType } from './page.type';
import
{
Link
,
CalendarFold
,
Book
}
from
'lucide-react'
;
import
{
Link
,
CalendarFold
,
Book
}
from
'lucide-react'
;
import
{
useEffect
,
useMemo
}
from
'react'
;
import
{
useEffect
,
useMemo
}
from
'react'
;
import
{
useParams
}
from
'next/navigation'
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'
// import { t } from 'i18next'
// Component
// Component
...
@@ -33,82 +36,34 @@ const NewsDetailPage = () => {
...
@@ -33,82 +36,34 @@ const NewsDetailPage = () => {
<
Spinner
/>
<
Spinner
/>
)
:
(
)
:
(
<
div
>
<
div
>
{
/* Banner */
}
<
div
className=
'container flex flex-col gap-5'
>
<
img
className=
'w-full h-100'
src=
{
`${BASE_URLS.imageEndpoint}${data?.responseData?.thumbnail}`
}
alt=
'Banner'
/>
<
ListCategory
categories=
{
MEDIA_INFORMATION_CATEGORIES
}
/>
{
/* Breadcrumb */
}
<
div
className=
"grid grid-cols-1 lg:grid-cols-3 gap-5"
>
<
div
className=
'container py-10'
>
{
/* Main content */
}
<
div
className=
'flex gap-4 items-stretch'
>
<
main
className=
"lg:col-span-2 bg-white border rounded-md p-7"
>
{
/* <Breadcrumbs aria-label='breadcrumb'>
<
div
className=
'pb-5 text-blue-900 text-2xl leading-normal font-medium'
>
<Link
{
data
?.
responseData
?.
title
}
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
>
</
div
>
<
div
className=
'flex items-center gap-2 text-sm mb-4'
>
{
/* date */
}
<
div
className=
'flex items-center gap-2 text-app-grey'
>
<
CalendarFold
/>
<
CalendarFold
/>
<
span
className=
'text-base'
>
{
dayjs
(
data
?.
responseData
?.
created_at
).
format
(
'DD/MM/YYYY'
)
}
</
span
>
<
span
className=
'text-base text-blue-700'
>
{
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
>
</
div
>
</
div
>
<
div
className=
'py-5'
>
<
hr
/>
</
div
>
</
div
>
{
/* Content */
}
<
div
className=
'flex-1 text-app-grey text-base overflow-hidden'
>
<
div
className=
'flex-1 text-app-grey text-base overflow-hidden'
>
<
AppEditorContent
value=
{
data
?.
responseData
?.
description
??
''
}
/>
<
AppEditorContent
value=
{
data
?.
responseData
?.
description
??
''
}
/>
</
div
>
</
div
>
</
main
>
{
/* Sidebar */
}
<
aside
className=
"space-y-6"
>
<
EventCalendar
/>
</
aside
>
</
div
>
</
div
>
</
div
>
</
div
>
{
/* Related News */
}
{
/* <RelatedNews newsQuery={getRelatedNewsQuery} lang={lang} newsId={infoNews.id} /> */
}
</
div
>
</
div
>
)
}
)
}
</
div
>
</
div
>
)
)
}
}
...
...
src/app/(main)/(home)/components/card-event/index.tsx
0 → 100644
View file @
227363b8
import
{
EventItem
}
from
'@/api/types/event'
import
BASE_URL
from
'@/links'
import
dayjs
from
'dayjs'
;
import
AppEditorContent
from
'@/components/shared/editor-content'
;
function
CardEvent
({
event
}:
{
event
:
EventItem
})
{
return
(
<
a
href=
{
`${event.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'
>
<
img
src=
{
`${BASE_URL.imageEndpoint}${event.image}`
}
alt=
{
event
.
name
}
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'
>
{
event
.
name
}
</
p
>
<
p
className=
'text-gray-500 text-sm my-1'
>
{
dayjs
(
event
.
start_time
).
format
(
'DD/MM/YYYY'
)
}
</
p
>
{
/* <AppEditorContent className='line-clamp-2' value={event.description} /> */
}
</
div
>
</
a
>
);
}
export
default
CardEvent
;
\ No newline at end of file
src/app/(main)/(home)/components/card-news/index.tsx
View file @
227363b8
...
@@ -7,12 +7,12 @@ function CardNews({ news }: { news: NewsAdminItem }) {
...
@@ -7,12 +7,12 @@ function CardNews({ news }: { news: NewsAdminItem }) {
return
(
return
(
<
a
<
a
href=
{
`${news.id}`
}
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
<
img
src=
{
`${BASE_URL.imageEndpoint}${news.thumbnail}`
}
src=
{
`${BASE_URL.imageEndpoint}${news.thumbnail}`
}
alt=
{
news
.
title
}
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'
>
<
div
className=
'flex-1'
>
<
p
className=
'text-[#0056b3] font-bold text-sm line-clamp-2'
>
<
p
className=
'text-[#0056b3] font-bold text-sm line-clamp-2'
>
...
...
src/app/(main)/(home)/page.tsx
View file @
227363b8
...
@@ -9,29 +9,32 @@ import 'swiper/css'
...
@@ -9,29 +9,32 @@ import 'swiper/css'
import
'swiper/css/navigation'
import
'swiper/css/navigation'
import
'swiper/css/pagination'
import
'swiper/css/pagination'
import
BASE_URL
from
'@/links/index'
import
BASE_URL
from
'@/links/index'
import
NewsContent
from
'./components/card-news'
import
{
Spinner
}
from
'@/components/ui'
import
{
Spinner
}
from
'@/components/ui'
import
CardNews
from
'./components/card-news'
import
CardEvent
from
'./components/card-event'
import
EventCalendar
from
'./components/event-calendar'
import
dayjs
from
'dayjs'
import
AppEditorContent
from
'@/components/shared/editor-content'
// server
import
{
useGetEvents
}
from
'@/api/endpoints/event'
import
{
useGetCategory
}
from
'@/api/endpoints/category'
import
{
useGetCategory
}
from
'@/api/endpoints/category'
import
{
useGetNews
}
from
'@/api/endpoints/news'
import
{
useGetNews
}
from
'@/api/endpoints/news'
import
{
GetCategoryAdminResponseType
}
from
'@/api/types/category'
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
{
EventApiResponse
,
EventItem
}
from
'@/api/types/event
'
const
Page
=
()
=>
{
const
Page
=
()
=>
{
const
[
tab
,
setTab
]
=
useState
(
'all'
)
const
[
tab
,
setTab
]
=
useState
(
'all'
)
const
[
search
,
setSearch
]
=
useState
(
''
)
const
[
submitSearch
,
setSubmitSearch
]
=
useState
(
''
)
const
[
currentIndex
,
setCurrentIndex
]
=
useState
(
0
)
const
[
currentIndex
,
setCurrentIndex
]
=
useState
(
0
)
const
[
slidesPerView
,
setSlidesPerView
]
=
useState
<
number
>
(
3
)
const
swiperRef
=
useRef
<
SwiperType
|
null
>
(
null
)
const
swiperRef
=
useRef
<
SwiperType
|
null
>
(
null
)
const
{
data
:
categoryData
}
=
useGetCategory
<
GetCategoryAdminResponseType
>
()
const
{
data
:
categoryData
,
isLoading
:
isLoadingCategory
}
=
useGetCategory
<
GetCategoryAdminResponseType
>
()
const
{
data
:
allData
,
isLoading
}
=
useGetNews
<
GetNewsAdminResponseType
>
({
const
{
data
:
newsData
,
isLoading
:
isLoadingNews
}
=
useGetNews
<
GetNewsAdminResponseType
>
()
pageSize
:
'999'
,
const
{
data
:
eventData
,
isLoading
:
isLoadingEvent
}
=
useGetEvents
<
EventApiResponse
>
()
filters
:
submitSearch
?
`title @=
${
submitSearch
}
`
:
undefined
,
})
const
rows
=
allData
?.
responseData
?.
rows
??
[]
// filter category
const
rows
=
newsData
?.
responseData
?.
rows
??
[]
const
filteredRows
=
tab
===
'all'
?
rows
:
rows
.
filter
((
n
)
=>
n
.
category
===
tab
)
const
filteredRows
=
tab
===
'all'
?
rows
:
rows
.
filter
((
n
)
=>
n
.
category
===
tab
)
const
images
=
[
const
images
=
[
...
@@ -64,19 +67,7 @@ const Page = () => {
...
@@ -64,19 +67,7 @@ const Page = () => {
'/home/hoi-vien-tieu-bieu/UOB-logo_Vuong.jpeg.webp'
,
'/home/hoi-vien-tieu-bieu/UOB-logo_Vuong.jpeg.webp'
,
]
]
useEffect
(()
=>
{
if
(
isLoadingNews
||
isLoadingCategory
||
isLoadingEvent
)
const
getSlides
=
(
w
:
number
)
=>
{
if
(
w
>=
1024
)
return
3
if
(
w
>=
640
)
return
2
return
1
}
const
update
=
()
=>
setSlidesPerView
(
getSlides
(
window
.
innerWidth
))
update
()
window
.
addEventListener
(
'resize'
,
update
)
return
()
=>
window
.
removeEventListener
(
'resize'
,
update
)
},
[])
if
(
isLoading
)
return
(
return
(
<
div
className=
"w-full h-[80vh] flex justify-center items-center"
>
<
div
className=
"w-full h-[80vh] flex justify-center items-center"
>
<
Spinner
/>
<
Spinner
/>
...
@@ -136,13 +127,13 @@ const Page = () => {
...
@@ -136,13 +127,13 @@ const Page = () => {
{
rows
.
map
((
news
)
=>
(
{
rows
.
map
((
news
)
=>
(
<
SwiperSlide
key=
{
news
.
id
}
>
<
SwiperSlide
key=
{
news
.
id
}
>
<
a
<
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"
className=
"relative block bg-white rounded-xl shadow-md overflow-hidden hover:shadow-lg transition-shadow duration-300"
>
>
<
img
<
img
src=
{
`${BASE_URL.imageEndpoint}${news.thumbnail}`
}
src=
{
`${BASE_URL.imageEndpoint}${news.thumbnail}`
}
alt=
{
news
.
title
}
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"
>
<
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"
>
<
p
className=
"text-white text-center font-semibold line-clamp-2 text-sm sm:text-base leading-snug"
>
...
@@ -166,20 +157,42 @@ const Page = () => {
...
@@ -166,20 +157,42 @@ const Page = () => {
{
/* Left */
}
{
/* Left */
}
<
div
className=
"flex-1"
>
<
div
className=
"flex-1"
>
<
div
className=
"flex justify-between items-center"
>
<
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
Tin tức
</
h2
>
</
a
>
<
a
href=
"
#"
className=
"text-blue-900 hover:underline
text-sm sm:text-base"
>
<
a
href=
"
/thong-tin-truyen-thong/tin-vcci/"
className=
"text-blue-900
text-sm sm:text-base"
>
{
'>>'
}
{
'>>'
}
</
a
>
</
a
>
</
div
>
</
div
>
<
hr
className=
"border-blue-900 mb-4"
/>
<
hr
className=
"border-blue-900 mb-4"
/>
<
div
className=
"flex flex-col md:flex-row gap-5"
>
<
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]"
>
{
newsData
?.
responseData
.
rows
.
slice
(
0
,
1
).
map
((
news
:
NewsAdminItem
)
=>
(
<
p
className=
"text-white text-center"
>
Khung tin tức VIP
</
p
>
<
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
>
<
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=
"w-full md:w-1/2"
>
<
div
className=
"flex flex-wrap gap-2 sm:gap-3 mb-3"
>
<
div
className=
"flex flex-wrap gap-2 sm:gap-3 mb-3"
>
<
button
<
button
...
@@ -205,8 +218,8 @@ const Page = () => {
...
@@ -205,8 +218,8 @@ const Page = () => {
))
}
))
}
</
div
>
</
div
>
{
filteredRows
.
slice
(
0
,
5
).
map
((
news
)
=>
(
{
filteredRows
.
slice
(
0
,
4
).
map
((
news
)
=>
(
<
NewsContent
key=
{
news
.
id
}
news=
{
news
}
/>
<
CardNews
key=
{
news
.
id
}
news=
{
news
}
/>
))
}
))
}
</
div
>
</
div
>
</
div
>
</
div
>
...
@@ -257,12 +270,34 @@ const Page = () => {
...
@@ -257,12 +270,34 @@ const Page = () => {
<
hr
className=
"border-[#e8c518] mb-4"
/>
<
hr
className=
"border-[#e8c518] mb-4"
/>
<
div
className=
"flex flex-col md:flex-row gap-5"
>
<
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]"
>
{
eventData
?.
responseData
.
rows
.
slice
(
0
,
1
).
map
((
event
:
EventItem
)
=>
(
<
p
className=
"text-white"
>
Khung tin tức VIP
</
p
>
<
a
key=
{
event
.
id
}
href=
{
`${event.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}${event.image}`
}
alt=
{
event
.
name
}
className=
"w-full h-full object-cover"
/>
</
div
>
</
div
>
<
div
className=
"flex-1"
>
<
p
className=
"text-[#0056b3] font-bold text-xl line-clamp-2"
>
{
event
.
name
}
</
p
>
<
p
className=
"text-gray-500 text-sm my-1"
>
{
dayjs
(
event
.
start_time
).
format
(
'DD/MM/YYYY'
)
}
</
p
>
<
AppEditorContent
className=
"line-clamp-3"
value=
{
event
.
description
}
/>
</
div
>
</
a
>
))
}
<
div
className=
"w-full md:w-1/2"
>
<
div
className=
"w-full md:w-1/2"
>
{
rows
.
slice
(
0
,
5
).
map
((
news
)
=>
(
{
eventData
?.
responseData
.
rows
.
slice
(
0
,
4
).
map
((
event
)
=>
(
<
NewsContent
key=
{
news
.
id
}
news=
{
news
}
/>
<
CardEvent
key=
{
event
.
id
}
event=
{
event
}
/>
))
}
))
}
</
div
>
</
div
>
</
div
>
</
div
>
...
@@ -294,33 +329,73 @@ const Page = () => {
...
@@ -294,33 +329,73 @@ const Page = () => {
<
section
className=
"flex flex-col md:flex-row gap-5 pt-8"
>
<
section
className=
"flex flex-col md:flex-row gap-5 pt-8"
>
<
div
className=
"flex-1"
>
<
div
className=
"flex-1"
>
<
div
className=
"flex justify-between items-center"
>
<
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
Cơ hội kinh doanh
</
h2
>
</
a
>
<
a
href=
"
#
"
className=
"text-blue-900 text-sm sm:text-base"
>
<
a
href=
"
/xuc-tien-thuong-mai/co-hoi-kinh-doanh/
"
className=
"text-blue-900 text-sm sm:text-base"
>
{
'>>'
}
{
'>>'
}
</
a
>
</
a
>
</
div
>
</
div
>
<
hr
className=
"border-blue-900 mb-4"
/>
<
hr
className=
"border-blue-900 mb-4"
/>
<
div
className=
"pt-2 space-y-3"
>
<
div
className=
"pt-2"
>
{
rows
.
slice
(
0
,
4
).
map
((
news
)
=>
(
{
newsData
?.
responseData
.
rows
.
slice
(
0
,
1
).
map
((
news
:
NewsAdminItem
)
=>
(
<
NewsContent
key=
{
news
.
id
}
news=
{
news
}
/>
<
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
)
=>
(
<
CardNews
key=
{
news
.
id
}
news=
{
news
}
/>
))
}
))
}
</
div
>
</
div
>
</
div
>
</
div
>
<
div
className=
"flex-1"
>
<
div
className=
"flex-1"
>
<
div
className=
"flex justify-between items-center"
>
<
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
Chính sách
&
pháp luật
</
h2
>
</
a
>
<
a
href=
"
#
"
className=
"text-blue-900 text-sm sm:text-base"
>
<
a
href=
"
/thong-tin-truyen-thong/thong-tin-chinh-sach-va-phap-luat
"
className=
"text-blue-900 text-sm sm:text-base"
>
{
'>>'
}
{
'>>'
}
</
a
>
</
a
>
</
div
>
</
div
>
<
hr
className=
"border-blue-900 mb-4"
/>
<
hr
className=
"border-blue-900 mb-4"
/>
<
div
className=
"pt-2 space-y-3"
>
<
div
className=
"pt-2"
>
{
rows
.
slice
(
0
,
4
).
map
((
news
)
=>
(
{
newsData
?.
responseData
.
rows
.
slice
(
0
,
1
).
map
((
news
:
NewsAdminItem
)
=>
(
<
NewsContent
key=
{
news
.
id
}
news=
{
news
}
/>
<
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
)
=>
(
<
CardNews
key=
{
news
.
id
}
news=
{
news
}
/>
))
}
))
}
</
div
>
</
div
>
</
div
>
</
div
>
...
@@ -331,12 +406,12 @@ const Page = () => {
...
@@ -331,12 +406,12 @@ const Page = () => {
<
img
src=
"/home/eCarAid_web_banner_600x400.webp"
alt=
"banner"
/>
<
img
src=
"/home/eCarAid_web_banner_600x400.webp"
alt=
"banner"
/>
</
a
>
</
a
>
</
div
>
</
div
>
</
div
>
</
div
>
{
/* Hội viên tiêu biểu */
}
{
/* 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 */
}
{
/* 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"
>
<
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
>
<
h2
className=
"text-xl font-bold uppercase text-blue-900"
>
Hội viên tiêu biểu
</
h2
>
<
a
<
a
...
@@ -374,10 +449,10 @@ const Page = () => {
...
@@ -374,10 +449,10 @@ const Page = () => {
))
}
))
}
</
Swiper
>
</
Swiper
>
</
div
>
</
div
>
</
aside
>
</
aside
>
{
/* right */
}
{
/* 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"
>
<
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
>
<
h2
className=
"text-xl font-bold uppercase text-blue-900"
>
Kết nối hội viên
</
h2
>
<
a
<
a
...
@@ -415,13 +490,13 @@ const Page = () => {
...
@@ -415,13 +490,13 @@ const Page = () => {
))
}
))
}
</
Swiper
>
</
Swiper
>
</
div
>
</
div
>
</
aside
>
</
aside
>
</
section
>
</
section
>
{
/* Video + đối tác */
}
{
/* 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 */
}
{
/* left */
}
<
div
className=
"flex flex-col flex-1"
>
<
div
className=
"flex flex-col flex-1"
>
<
div
className=
"flex justify-between items-center mb-3"
>
<
div
className=
"flex justify-between items-center mb-3"
>
<
h2
className=
"text-xl font-bold uppercase text-blue-900"
>
Video
</
h2
>
<
h2
className=
"text-xl font-bold uppercase text-blue-900"
>
Video
</
h2
>
<
a
<
a
...
@@ -459,10 +534,10 @@ const Page = () => {
...
@@ -459,10 +534,10 @@ const Page = () => {
</
div
>
</
div
>
))
}
))
}
</
div
>
</
div
>
</
div
>
</
div
>
{
/* right */
}
{
/* right */
}
<
aside
className=
"w-full lg:w-[30%]"
>
<
aside
className=
"w-full lg:w-[30%]"
>
<
div
className=
"flex justify-between items-center mb-3"
>
<
div
className=
"flex justify-between items-center mb-3"
>
<
h2
className=
"text-xl font-bold uppercase text-blue-900"
>
Đối tác
</
h2
>
<
h2
className=
"text-xl font-bold uppercase text-blue-900"
>
Đối tác
</
h2
>
<
a
<
a
...
@@ -500,9 +575,9 @@ const Page = () => {
...
@@ -500,9 +575,9 @@ const Page = () => {
))
}
))
}
</
Swiper
>
</
Swiper
>
</
div
>
</
div
>
</
aside
>
</
aside
>
</
section
>
</
section
>
</
div
>
</
div
>
</>
</>
)
)
}
}
...
...
src/components/base/card-news/index.tsx
View file @
227363b8
...
@@ -3,7 +3,7 @@ import { NewsItem } from '@app/dai-dien-gioi-chu/lib/types/NewsPage.type';
...
@@ -3,7 +3,7 @@ import { NewsItem } from '@app/dai-dien-gioi-chu/lib/types/NewsPage.type';
import
Links
from
'@links/index'
import
Links
from
'@links/index'
import
dayjs
from
'dayjs'
;
import
dayjs
from
'dayjs'
;
import
parse
from
'html-react-parser'
import
parse
from
'html-react-parser'
function
NewsContent
({
news
,
link
}:
{
news
:
NewsItem
,
link
:
string
})
{
function
NewsContent
({
news
,
link
}:
{
news
:
NewsItem
,
link
:
string
})
{
return
(
return
(
<
a
<
a
...
@@ -17,11 +17,10 @@ function NewsContent({ news ,link}: { news: NewsItem ,link:string}) {
...
@@ -17,11 +17,10 @@ function NewsContent({ news ,link}: { news: NewsItem ,link:string}) {
onError=
{
(
e
)
=>
{
onError=
{
(
e
)
=>
{
e
.
currentTarget
.
src
=
"/img-error.png"
e
.
currentTarget
.
src
=
"/img-error.png"
}
}
}
}
/>
/>
<
div
className=
"flex-1 min-w-0 pl-0 sm:pl-4"
>
<
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
}
{
news
.
title
}
</
p
>
</
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