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
e83b5a22
Commit
e83b5a22
authored
Nov 04, 2025
by
Phạm Quang Bảo
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
update/add event into page
parent
c2d14537
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
135 additions
and
42 deletions
+135
-42
event.ts
src/api/types/event.ts
+74
-0
index.tsx
src/app/(main)/(home)/components/card-event/index.tsx
+30
-0
page.tsx
src/app/(main)/(home)/page.tsx
+31
-42
No files found.
src/api/types/event.ts
0 → 100644
View file @
e83b5a22
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)/components/card-event/index.tsx
0 → 100644
View file @
e83b5a22
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)/page.tsx
View file @
e83b5a22
...
...
@@ -9,31 +9,32 @@ import 'swiper/css'
import
'swiper/css/navigation'
import
'swiper/css/pagination'
import
BASE_URL
from
'@/links/index'
import
NewsContent
from
'./components/card-news'
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
{
useGetNews
}
from
'@/api/endpoints/news'
import
{
GetCategoryAdminResponseType
}
from
'@/api/types/category'
import
{
GetNewsAdminResponseType
,
NewsAdminItem
}
from
'@/api/types/news'
import
EventCalendar
from
'./components/event-calendar'
import
dayjs
from
'dayjs'
import
AppEditorContent
from
'@/components/shared/editor-content'
import
{
EventApiResponse
,
EventItem
}
from
'@/api/types/event'
const
Page
=
()
=>
{
const
[
tab
,
setTab
]
=
useState
(
'all'
)
const
[
search
,
setSearch
]
=
useState
(
''
)
const
[
submitSearch
,
setSubmitSearch
]
=
useState
(
''
)
const
[
currentIndex
,
setCurrentIndex
]
=
useState
(
0
)
const
[
slidesPerView
,
setSlidesPerView
]
=
useState
<
number
>
(
3
)
const
swiperRef
=
useRef
<
SwiperType
|
null
>
(
null
)
const
{
data
:
categoryData
}
=
useGetCategory
<
GetCategoryAdminResponseType
>
()
const
{
data
:
allData
,
isLoading
}
=
useGetNews
<
GetNewsAdminResponseType
>
({
pageSize
:
'999'
,
filters
:
submitSearch
?
`title @=
${
submitSearch
}
`
:
undefined
,
})
const
{
data
:
categoryData
,
isLoading
:
isLoadingCategory
}
=
useGetCategory
<
GetCategoryAdminResponseType
>
()
const
{
data
:
newsData
,
isLoading
:
isLoadingNews
}
=
useGetNews
<
GetNewsAdminResponseType
>
()
const
{
data
:
eventData
,
isLoading
:
isLoadingEvent
}
=
useGetEvents
<
EventApiResponse
>
()
const
rows
=
allData
?.
responseData
?.
rows
??
[]
// filter category
const
rows
=
newsData
?.
responseData
?.
rows
??
[]
const
filteredRows
=
tab
===
'all'
?
rows
:
rows
.
filter
((
n
)
=>
n
.
category
===
tab
)
const
images
=
[
...
...
@@ -66,19 +67,7 @@ const Page = () => {
'/home/hoi-vien-tieu-bieu/UOB-logo_Vuong.jpeg.webp'
,
]
useEffect
(()
=>
{
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
)
if
(
isLoadingNews
||
isLoadingCategory
||
isLoadingEvent
)
return
(
<
div
className=
"w-full h-[80vh] flex justify-center items-center"
>
<
Spinner
/>
...
...
@@ -178,7 +167,7 @@ const Page = () => {
<
hr
className=
"border-blue-900 mb-4"
/>
<
div
className=
"flex flex-col md:flex-row gap-5"
>
{
all
Data
?.
responseData
.
rows
.
slice
(
0
,
1
).
map
((
news
:
NewsAdminItem
)
=>
(
{
news
Data
?.
responseData
.
rows
.
slice
(
0
,
1
).
map
((
news
:
NewsAdminItem
)
=>
(
<
a
key=
{
news
.
id
}
href=
{
`${news.id}`
}
...
...
@@ -230,7 +219,7 @@ const Page = () => {
</
div
>
{
filteredRows
.
slice
(
0
,
4
).
map
((
news
)
=>
(
<
NewsContent
key=
{
news
.
id
}
news=
{
news
}
/>
<
CardNews
key=
{
news
.
id
}
news=
{
news
}
/>
))
}
</
div
>
</
div
>
...
...
@@ -281,34 +270,34 @@ const Page = () => {
<
hr
className=
"border-[#e8c518] mb-4"
/>
<
div
className=
"flex flex-col md:flex-row gap-5"
>
{
allData
?.
responseData
.
rows
.
slice
(
0
,
1
).
map
((
news
:
NewsAdmin
Item
)
=>
(
{
eventData
?.
responseData
.
rows
.
slice
(
0
,
1
).
map
((
event
:
Event
Item
)
=>
(
<
a
key=
{
news
.
id
}
href=
{
`${
news
.id}`
}
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}${
news.thumbnail
}`
}
alt=
{
news
.
titl
e
}
src=
{
`${BASE_URL.imageEndpoint}${
event.image
}`
}
alt=
{
event
.
nam
e
}
className=
"w-full h-full object-cover"
/>
</
div
>
<
div
className=
"flex-1"
>
<
p
className=
"text-[#0056b3] font-bold text-xl line-clamp-2"
>
{
news
.
titl
e
}
{
event
.
nam
e
}
</
p
>
<
p
className=
"text-gray-500 text-sm my-1"
>
{
dayjs
(
news
.
release_at
).
format
(
'DD/MM/YYYY'
)
}
{
dayjs
(
event
.
start_time
).
format
(
'DD/MM/YYYY'
)
}
</
p
>
<
AppEditorContent
className=
"line-clamp-3"
value=
{
news
.
description
}
/>
<
AppEditorContent
className=
"line-clamp-3"
value=
{
event
.
description
}
/>
</
div
>
</
a
>
))
}
<
div
className=
"w-full md:w-1/2"
>
{
rows
.
slice
(
0
,
4
).
map
((
news
)
=>
(
<
NewsContent
key=
{
news
.
id
}
news=
{
news
}
/>
{
eventData
?.
responseData
.
rows
.
slice
(
0
,
4
).
map
((
event
)
=>
(
<
CardEvent
key=
{
event
.
id
}
event=
{
event
}
/>
))
}
</
div
>
</
div
>
...
...
@@ -349,7 +338,7 @@ const Page = () => {
</
div
>
<
hr
className=
"border-blue-900 mb-4"
/>
<
div
className=
"pt-2"
>
{
all
Data
?.
responseData
.
rows
.
slice
(
0
,
1
).
map
((
news
:
NewsAdminItem
)
=>
(
{
news
Data
?.
responseData
.
rows
.
slice
(
0
,
1
).
map
((
news
:
NewsAdminItem
)
=>
(
<
a
key=
{
news
.
id
}
href=
{
`${news.id}`
}
...
...
@@ -370,7 +359,7 @@ const Page = () => {
))
}
{
rows
.
slice
(
0
,
3
).
map
((
news
)
=>
(
<
NewsContent
key=
{
news
.
id
}
news=
{
news
}
/>
<
CardNews
key=
{
news
.
id
}
news=
{
news
}
/>
))
}
</
div
>
</
div
>
...
...
@@ -385,7 +374,7 @@ const Page = () => {
</
div
>
<
hr
className=
"border-blue-900 mb-4"
/>
<
div
className=
"pt-2"
>
{
all
Data
?.
responseData
.
rows
.
slice
(
0
,
1
).
map
((
news
:
NewsAdminItem
)
=>
(
{
news
Data
?.
responseData
.
rows
.
slice
(
0
,
1
).
map
((
news
:
NewsAdminItem
)
=>
(
<
a
key=
{
news
.
id
}
href=
{
`${news.id}`
}
...
...
@@ -406,7 +395,7 @@ const Page = () => {
))
}
{
rows
.
slice
(
0
,
3
).
map
((
news
)
=>
(
<
NewsContent
key=
{
news
.
id
}
news=
{
news
}
/>
<
CardNews
key=
{
news
.
id
}
news=
{
news
}
/>
))
}
</
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