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
74a04b88
Commit
74a04b88
authored
Nov 05, 2025
by
Vũ Đình Nguyên
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
update layout
parent
6c996526
Changes
28
Hide whitespace changes
Inline
Side-by-side
Showing
28 changed files
with
750 additions
and
377 deletions
+750
-377
event.ts
src/api/types/event.ts
+64
-2
header.tsx
src/app/(main)/_lib/layout/header.tsx
+27
-29
page.tsx
src/app/(main)/dai-dien-gioi-chu/chu-de/page.tsx
+30
-20
index.tsx
...p/(main)/dai-dien-gioi-chu/components/card-news/index.tsx
+7
-7
page.tsx
src/app/(main)/dai-dien-gioi-chu/tap-huan-nsdld/page.tsx
+30
-20
page.tsx
src/app/(main)/dai-dien-gioi-chu/tin-lien-quan/page.tsx
+23
-13
page.tsx
src/app/(main)/hoat-dong/dao-tao/page.tsx
+23
-13
page.tsx
src/app/(main)/hoat-dong/su-kien/[id]/page.tsx
+16
-5
page.tsx
src/app/(main)/hoat-dong/su-kien/page.tsx
+28
-14
page.tsx
src/app/(main)/hoi-vien/ket-noi-hoi-vien/page.tsx
+29
-19
page.tsx
src/app/(main)/hoi-vien/tin-hoi-vien/page.tsx
+29
-19
page.tsx
src/app/(main)/search/page.tsx
+34
-24
page.tsx
src/app/(main)/thong-tin-truyen-thong/chuyen-de/page.tsx
+28
-19
page.tsx
...n-truyen-thong/thong-tin-chinh-sach-va-phap-luat/page.tsx
+2
-2
page.tsx
.../(main)/thong-tin-truyen-thong/thu-vien-tai-lieu/page.tsx
+28
-19
page.tsx
...p/(main)/thong-tin-truyen-thong/tin-doanh-nghiep/page.tsx
+28
-19
page.tsx
src/app/(main)/thong-tin-truyen-thong/tin-kinh-te/page.tsx
+28
-19
page.tsx
src/app/(main)/thong-tin-truyen-thong/tin-vcci/page.tsx
+27
-19
page.tsx
src/app/(main)/xuc-tien-thuong-mai/[id]/page.tsx
+12
-2
page.tsx
...main)/xuc-tien-thuong-mai/co-hoi-kinh-doanh/[id]/page.tsx
+14
-2
page.tsx
...app/(main)/xuc-tien-thuong-mai/co-hoi-kinh-doanh/page.tsx
+32
-20
page.tsx
...main)/xuc-tien-thuong-mai/ho-tro-kinh-doanh/[id]/page.tsx
+14
-2
page.tsx
...app/(main)/xuc-tien-thuong-mai/ho-tro-kinh-doanh/page.tsx
+36
-24
page.tsx
...)/xuc-tien-thuong-mai/moi-truong-kinh-doanh/[id]/page.tsx
+14
-2
page.tsx
...(main)/xuc-tien-thuong-mai/moi-truong-kinh-doanh/page.tsx
+36
-24
page.tsx
src/app/(main)/xuc-tien-thuong-mai/page.tsx
+29
-19
loading-state.tsx
src/components/ui/loading-state.tsx
+49
-0
common.ts
src/lib/types/common.ts
+33
-0
No files found.
src/api/types/event.ts
View file @
74a04b88
import
{
ResponseType
}
from
'@lib/types/common'
export
type
EventStatus
=
{
id
:
string
;
name
:
string
;
...
...
@@ -22,7 +23,68 @@ export type EventOrganization = {
add_info
:
unknown
|
null
;
organization
:
unknown
|
null
;
};
// useGetEventsId
export
type
GetEventsIdQueryResponseType
=
ResponseType
<
{
accept_entries
:
boolean
|
null
counter_cost
:
number
counter_count
:
number
created_at
:
string
description
:
string
end_time
:
string
event_organizations
:
Array
<
{
add_info
:
string
|
null
created_at
:
string
guest_image
:
string
|
null
guest_name
:
string
|
null
id
:
string
org_counter_count
:
number
|
null
org_table_count
:
number
|
null
organization
:
{
address
:
string
avatar
:
string
|
null
club_link
:
string
|
null
club_name
:
string
|
null
id
:
string
name
:
string
org_categories
:
string
[]
org_link
:
string
|
null
org_status_id
:
string
|
null
organization_products
:
Array
<
{
id
:
string
images
:
string
[]
}
>
province
:
string
[]
tax_code
:
string
users
:
Array
<
{
id
:
string
}
>
website
:
string
}
|
null
role
:
'PARTAKER'
|
'MAIN'
|
'SUPPORT'
|
'SUPPORT_1'
|
'SUPPORT_2'
|
'SUPPORT_3'
|
'GUEST'
status
:
string
|
null
}
>
host_club
:
string
|
null
id
:
string
image
:
string
introduction
:
string
|
null
location
:
string
name
:
string
org_support_titles
:
string
[]
|
null
province
:
string
seo_text
:
string
seo_text_en
:
string
|
null
start_time
:
string
status
:
string
status_status
:
{
code
:
string
id
:
string
name
:
string
name_en
:
string
}
table_cost
:
number
table_count
:
number
updated_at
:
string
|
null
}
>
export
type
EventItem
=
{
id
:
string
;
name
:
string
;
...
...
@@ -71,4 +133,4 @@ export type EventApiResponse = {
status
:
string
;
timeStamp
:
string
;
violations
:
null
|
unknown
;
};
\ No newline at end of file
};
src/app/(main)/_lib/layout/header.tsx
View file @
74a04b88
"use client"
;
import
React
,
{
useState
}
from
"react"
;
import
{
useRouter
}
from
'next/navigation'
import
{
useRouter
}
from
"next/navigation"
;
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"
;
...
...
@@ -8,33 +8,33 @@ import MenuItem from "./MenuItem";
import
Link
from
"next/link"
;
function
Header
()
{
const
[
toggleMenu
,
setToggleMenu
]
=
useState
<
boolean
>
(
false
);
const
router
=
useRouter
()
const
router
=
useRouter
()
;
return
(
<>
<
div
className=
"sticky top-0 w-full h-
[56px]
hidden lg:flex items-center justify-center bg-[#063e8e]"
>
<
div
className=
"sticky top-0 w-full h-
14
hidden lg:flex items-center justify-center bg-[#063e8e]"
>
<
div
className=
"container 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=
"
#
"
<
div
className=
"w-[130px] h-
9
bg-[#e8c518] flex items-center justify-center border-4 rounded-sm border-[#647792]"
>
<
Link
className=
"font-
semibold text-[14px] text-primary
hover:text-white transition"
href=
"
https://vccihcm.vn/dang-ky
"
>
Đăng Ký Hội Viên
</
a
>
</
Link
>
</
div
>
<
a
<
Link
className=
"px-3 py-2 text-[14px] text-white hover:opacity-80"
href=
"
#
"
href=
"
/site-map
"
>
Sitemap
</
a
>
<
a
</
Link
>
<
Link
className=
"px-3 py-2 text-[14px] text-white hover:opacity-80"
href=
"
#
"
href=
"
https://vccihcm.vn/lien-he
"
>
Liên hệ
</
a
>
</
Link
>
</
div
>
<
div
className=
"flex items-center gap-8"
>
...
...
@@ -43,10 +43,11 @@ function Header() {
type=
"text"
placeholder=
"Tìm kiếm"
onKeyDown=
{
(
e
)
=>
{
if
(
e
.
key
===
'Enter'
)
{
const
value
=
(
e
.
currentTarget
as
HTMLInputElement
).
value
||
''
const
encoded
=
encodeURIComponent
(
value
)
router
.
push
(
`/search?q=${encoded}`
)
if
(
e
.
key
===
"Enter"
)
{
const
value
=
(
e
.
currentTarget
as
HTMLInputElement
).
value
||
""
;
const
encoded
=
encodeURIComponent
(
value
);
router
.
push
(
`/search?q=${encoded}`
);
}
}
}
/>
...
...
@@ -92,12 +93,11 @@ function Header() {
{
title
:
"Sơ Đồ Tổ Chức"
,
link
:
"so-do-to-chuc"
},
{
title
:
"Dịch Vụ Cung Cấp"
,
link
:
"dich-vu-cung-cap"
},
]
}
/>
<
MenuItem
title=
"Hội viên"
link=
"hoi-vien"
items=
{
[
items=
{
[
{
title
:
"Lợi Ích Của Hội Viên VCCI"
,
link
:
""
,
...
...
@@ -106,16 +106,15 @@ function Header() {
{
title
:
"Kết Nối Hội Viên"
,
link
:
"ket-noi-hoi-vien"
},
{
title
:
"Tin Hội Viên"
,
link
:
"tin-hoi-vien"
},
]
}
/>
<
MenuItem
title=
"Hoạt động"
link=
"hoat-dong"
items=
{
[
items=
{
[
{
title
:
"Sự Kiện"
,
link
:
""
},
{
title
:
"Đào Tạo"
,
link
:
"dao-tao"
},
]
}
/>
/>
<
MenuItem
title=
"Xuất Xứ Hàng Hóa"
link=
"xuat-xu-hang-hoa"
...
...
@@ -198,7 +197,7 @@ function Header() {
<
MenuItem
title=
"Xúc tiến thương mại"
link=
"xuc-tien-thuong-mai"
items=
{
[
items=
{
[
{
title
:
"Hồ Sơ Thị Trường"
,
link
:
"ho-so-thi-truong"
},
{
title
:
"Môi Trường Kinh Doanh"
,
...
...
@@ -207,12 +206,11 @@ function Header() {
{
title
:
"Cơ Hội Kinh Doanh"
,
link
:
"co-hoi-kinh-doanh"
},
{
title
:
"Hỗ Trợ Kinh Doanh"
,
link
:
"ho-tro-kinh-doanh"
},
]
}
/>
<
MenuItem
title=
"Thông tin truyền thông"
link=
"thong-tin-truyen-thong"
items=
{
[
items=
{
[
{
title
:
"Tin VCCI"
,
link
:
"tin-vcci"
},
{
title
:
"Tin Kinh Tế"
,
link
:
"tin-kinh-te"
},
{
title
:
"Tin Doanh Nghiệp"
,
link
:
"tin-doanh-nghiep"
},
...
...
@@ -224,7 +222,6 @@ function Header() {
{
title
:
"Ấn Phẩm"
,
link
:
"an-pham"
},
{
title
:
"Thư Viện Tài Liệu"
,
link
:
"thu-vien-tai-lieu"
},
]
}
/>
</
nav
>
...
...
@@ -240,8 +237,9 @@ function Header() {
{
/* 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"
}`
}
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"
,
...
...
src/app/(main)/dai-dien-gioi-chu/chu-de/page.tsx
View file @
74a04b88
...
...
@@ -9,12 +9,13 @@ import Image from "next/image";
import
{
useGetNews
}
from
"@api/endpoints/news"
;
import
{
GetNewsResponseType
}
from
"@api/types/NewsPage.type"
;
import
{
PATHS
}
from
"@constants/paths"
;
import
{
Spinner
}
from
"@components/ui/spinner"
;
export
default
function
Page
()
{
const
[
submitSearch
]
=
useState
(
""
);
const
[
page
,
setPage
]
=
useState
(
1
);
const
pageSize
=
5
;
const
{
data
:
allData
}
=
useGetNews
<
GetNewsResponseType
>
({
const
{
data
:
allData
,
isLoading
}
=
useGetNews
<
GetNewsResponseType
>
({
pageSize
:
String
(
pageSize
),
currentPage
:
String
(
page
),
// filters: submitSearch ? `title @=${submitSearch}` : undefined,
...
...
@@ -29,26 +30,35 @@ export default function Page() {
{
/* Main content */
}
<
main
className=
"lg:col-span-2 bg-background "
>
<
div
className=
"pb-5 overflow-hidden"
>
{
allData
?.
responseData
.
rows
.
map
((
news
)
=>
(
<
NewsContent
key=
{
news
.
id
}
news=
{
news
}
link=
{
`${PATHS.ownerRepresentatives}/chu-de/${news.id}`
}
/>
))
}
{
isLoading
?
(
<
div
className=
"flex justify-center items-center py-12"
>
<
Spinner
className=
"size-8"
/>
<
span
className=
"ml-2 text-gray-600"
>
Đang tải dữ liệu...
</
span
>
</
div
>
)
:
(
<>
{
allData
?.
responseData
.
rows
.
map
((
news
)
=>
(
<
NewsContent
key=
{
news
.
id
}
news=
{
news
}
link=
{
`${PATHS.ownerRepresentatives}/chu-de/${news.id}`
}
/>
))
}
<
div
className=
"w-full flex justify-center mt-4"
>
<
Pagination
pageCount=
{
Number
(
allData
?.
responseData
.
totalPages
??
1
)
}
page=
{
Number
(
allData
?.
responseData
.
currentPage
??
page
)
}
onChangePage=
{
(
p
)
=>
setPage
(
p
)
}
onGoToPreviousPage=
{
()
=>
setPage
(
Math
.
max
(
1
,
page
-
1
))
}
onGoToNextPage=
{
()
=>
setPage
(
Math
.
min
(
Number
(
allData
?.
responseData
.
totalPages
??
1
),
page
+
1
)
)
}
/>
</
div
>
<
div
className=
"w-full flex justify-center mt-4"
>
<
Pagination
pageCount=
{
Number
(
allData
?.
responseData
.
totalPages
??
1
)
}
page=
{
Number
(
allData
?.
responseData
.
currentPage
??
page
)
}
onChangePage=
{
(
p
)
=>
setPage
(
p
)
}
onGoToPreviousPage=
{
()
=>
setPage
(
Math
.
max
(
1
,
page
-
1
))
}
onGoToNextPage=
{
()
=>
setPage
(
Math
.
min
(
Number
(
allData
?.
responseData
.
totalPages
??
1
),
page
+
1
)
)
}
/>
</
div
>
</>
)
}
</
div
>
</
main
>
...
...
src/app/(main)/dai-dien-gioi-chu/components/card-news/index.tsx
View file @
74a04b88
...
...
@@ -2,7 +2,7 @@
import
{
NewsItem
}
from
'@app/dai-dien-gioi-chu/lib/types/NewsPage.type'
;
import
Links
from
'@links/index'
import
dayjs
from
'dayjs'
;
import
{
EventItem
}
from
"@api/types/event"
;
// Helper: remove <img> tags and extract plain text from HTML
const
stripImagesAndHtml
=
(
html
?:
string
)
=>
{
if
(
!
html
)
return
''
...
...
@@ -19,7 +19,7 @@ const stripImagesAndHtml = (html?: string) => {
}
return
withoutImgs
.
replace
(
/<
[^
>
]
*>/g
,
''
)
}
function
NewsContent
({
news
,
link
}:
{
news
:
NewsItem
,
link
:
string
})
{
function
NewsContent
({
news
,
link
,
event
}:
{
news
?:
NewsItem
,
link
:
string
,
event
?:
EventItem
})
{
return
(
<
a
...
...
@@ -27,8 +27,8 @@ function NewsContent({ news ,link}: { news: NewsItem ,link:string}) {
className=
"flex flex-col hover:no-underline sm:flex-row gap-2 mb-6 bg-white rounded-lg shadow-sm p-4 border items-start min-w-0"
>
<
img
src=
{
`${Links.imageEndpoint}${news
.thumbnail
}`
}
alt=
{
news
.
titl
e
}
src=
{
`${Links.imageEndpoint}${news
?news.thumbnail:event?.image
}`
}
alt=
{
news
?
news
.
title
:
event
?.
nam
e
}
className=
"w-full sm:w-56 md:w-64 h-40 md:h-36 object-cover shrink-0"
onError=
{
(
e
)
=>
{
e
.
currentTarget
.
src
=
"/img-error.png"
...
...
@@ -38,13 +38,13 @@ function NewsContent({ news ,link}: { news: NewsItem ,link:string}) {
<
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"
>
{
news
.
titl
e
}
{
news
?.
title
}{
event
?.
nam
e
}
</
p
>
<
div
className=
"text-sm my-2 text-[#00AED5]"
>
{
dayjs
(
news
.
release
_at
).
format
(
'DD/MM/YYYY'
)
}
</
div
>
<
div
className=
"text-sm my-2 text-[#00AED5]"
>
{
dayjs
(
news
?
news
?.
created_at
:
event
?.
created
_at
).
format
(
'DD/MM/YYYY'
)
}
</
div
>
<
div
className=
"text-sm text-[#777] line-clamp-3"
>
<
div
className=
"text-sm prose tiptap"
>
{
stripImagesAndHtml
(
news
.
description
)
}
</
div
>
<
div
className=
"text-sm prose tiptap"
>
{
stripImagesAndHtml
(
news
?
news
.
description
:
event
?
.
description
)
}
</
div
>
</
div
>
</
div
>
</
a
>
...
...
src/app/(main)/dai-dien-gioi-chu/tap-huan-nsdld/page.tsx
View file @
74a04b88
...
...
@@ -9,12 +9,13 @@ import Image from "next/image";
import
{
useGetNews
}
from
"@api/endpoints/news"
;
import
{
GetNewsResponseType
}
from
"@api/types/NewsPage.type"
;
import
{
PATHS
}
from
"@constants/paths"
;
import
{
Spinner
}
from
"@components/ui/spinner"
;
export
default
function
Page
()
{
const
[
submitSearch
]
=
useState
(
""
);
const
[
page
,
setPage
]
=
useState
(
1
);
const
pageSize
=
5
;
const
{
data
:
allData
}
=
useGetNews
<
GetNewsResponseType
>
({
const
{
data
:
allData
,
isLoading
}
=
useGetNews
<
GetNewsResponseType
>
({
pageSize
:
String
(
pageSize
),
currentPage
:
String
(
page
),
filters
:
submitSearch
?
`title @=
${
submitSearch
}
`
:
undefined
,
...
...
@@ -28,26 +29,35 @@ export default function Page() {
{
/* Main content */
}
<
main
className=
"lg:col-span-2 bg-background "
>
<
div
className=
"pb-5 overflow-hidden"
>
{
allData
?.
responseData
.
rows
.
map
((
news
)
=>
(
<
NewsContent
key=
{
news
.
id
}
news=
{
news
}
link=
{
`${PATHS.ownerRepresentatives}/tap-huan-nsdld/${news.id}`
}
/>
))
}
{
isLoading
?
(
<
div
className=
"flex justify-center items-center py-12"
>
<
Spinner
className=
"size-8"
/>
<
span
className=
"ml-2 text-gray-600"
>
Đang tải tập huấn NSDLĐ...
</
span
>
</
div
>
)
:
(
<>
{
allData
?.
responseData
.
rows
.
map
((
news
)
=>
(
<
NewsContent
key=
{
news
.
id
}
news=
{
news
}
link=
{
`${PATHS.ownerRepresentatives}/tap-huan-nsdld/${news.id}`
}
/>
))
}
<
div
className=
"w-full flex justify-center mt-4"
>
<
Pagination
pageCount=
{
Number
(
allData
?.
responseData
.
totalPages
??
1
)
}
page=
{
Number
(
allData
?.
responseData
.
currentPage
??
page
)
}
onChangePage=
{
(
p
)
=>
setPage
(
p
)
}
onGoToPreviousPage=
{
()
=>
setPage
(
Math
.
max
(
1
,
page
-
1
))
}
onGoToNextPage=
{
()
=>
setPage
(
Math
.
min
(
Number
(
allData
?.
responseData
.
totalPages
??
1
),
page
+
1
)
)
}
/>
</
div
>
<
div
className=
"w-full flex justify-center mt-4"
>
<
Pagination
pageCount=
{
Number
(
allData
?.
responseData
.
totalPages
??
1
)
}
page=
{
Number
(
allData
?.
responseData
.
currentPage
??
page
)
}
onChangePage=
{
(
p
)
=>
setPage
(
p
)
}
onGoToPreviousPage=
{
()
=>
setPage
(
Math
.
max
(
1
,
page
-
1
))
}
onGoToNextPage=
{
()
=>
setPage
(
Math
.
min
(
Number
(
allData
?.
responseData
.
totalPages
??
1
),
page
+
1
)
)
}
/>
</
div
>
</>
)
}
</
div
>
</
main
>
...
...
src/app/(main)/dai-dien-gioi-chu/tin-lien-quan/page.tsx
View file @
74a04b88
...
...
@@ -9,12 +9,13 @@ import Image from "next/image";
import
{
useGetNews
}
from
"@api/endpoints/news"
;
import
{
GetNewsResponseType
}
from
"@api/types/NewsPage.type"
;
import
{
PATHS
}
from
"@constants/paths"
;
import
{
Spinner
}
from
"@components/ui/spinner"
;
export
default
function
Page
()
{
const
[
submitSearch
,
setsubmitSearch
]
=
useState
(
""
);
const
[
page
,
setPage
]
=
useState
(
1
);
const
pageSize
=
5
;
const
{
data
:
allData
}
=
useGetNews
<
GetNewsResponseType
>
({
const
{
data
:
allData
,
isLoading
}
=
useGetNews
<
GetNewsResponseType
>
({
pageSize
:
String
(
pageSize
),
currentPage
:
String
(
page
),
filters
:
submitSearch
?
`title @=
${
submitSearch
}
,category@=Tin liên quan`
:
'category@=Tin liên quan'
,
...
...
@@ -28,19 +29,28 @@ export default function Page() {
{
/* Main content */
}
<
main
className=
"lg:col-span-2 bg-background "
>
<
div
className=
"pb-5 overflow-hidden"
>
{
allData
?.
responseData
.
rows
.
map
((
news
)
=>
(
<
NewsContent
key=
{
news
.
id
}
news=
{
news
}
link=
{
`${PATHS.ownerRepresentatives}/tin-lien-quan/${news.id}`
}
/>
))
}
{
isLoading
?
(
<
div
className=
"flex justify-center items-center py-12"
>
<
Spinner
className=
"size-8"
/>
<
span
className=
"ml-2 text-gray-600"
>
Đang tải tin liên quan...
</
span
>
</
div
>
)
:
(
<>
{
allData
?.
responseData
.
rows
.
map
((
news
)
=>
(
<
NewsContent
key=
{
news
.
id
}
news=
{
news
}
link=
{
`${PATHS.ownerRepresentatives}/tin-lien-quan/${news.id}`
}
/>
))
}
<
div
className=
"w-full flex justify-center mt-4"
>
<
Pagination
pageCount=
{
Number
(
allData
?.
responseData
.
totalPages
??
1
)
}
page=
{
Number
(
allData
?.
responseData
.
currentPage
??
page
)
}
onChangePage=
{
(
p
)
=>
setPage
(
p
)
}
onGoToPreviousPage=
{
()
=>
setPage
(
Math
.
max
(
1
,
page
-
1
))
}
onGoToNextPage=
{
()
=>
setPage
(
Math
.
min
(
Number
(
allData
?.
responseData
.
totalPages
??
1
),
page
+
1
))
}
/>
</
div
>
<
div
className=
"w-full flex justify-center mt-4"
>
<
Pagination
pageCount=
{
Number
(
allData
?.
responseData
.
totalPages
??
1
)
}
page=
{
Number
(
allData
?.
responseData
.
currentPage
??
page
)
}
onChangePage=
{
(
p
)
=>
setPage
(
p
)
}
onGoToPreviousPage=
{
()
=>
setPage
(
Math
.
max
(
1
,
page
-
1
))
}
onGoToNextPage=
{
()
=>
setPage
(
Math
.
min
(
Number
(
allData
?.
responseData
.
totalPages
??
1
),
page
+
1
))
}
/>
</
div
>
</>
)
}
</
div
>
</
main
>
...
...
src/app/(main)/hoat-dong/dao-tao/page.tsx
View file @
74a04b88
...
...
@@ -9,12 +9,13 @@ import Image from "next/image";
import
{
useGetNews
}
from
"@api/endpoints/news"
;
import
{
GetNewsResponseType
}
from
"@api/types/NewsPage.type"
;
import
{
PATHS
}
from
"@constants/paths"
;
import
{
Spinner
}
from
"@components/ui/spinner"
;
export
default
function
Page
()
{
const
[
submitSearch
]
=
useState
(
""
);
const
[
page
,
setPage
]
=
useState
(
1
);
const
pageSize
=
5
;
const
{
data
:
allData
}
=
useGetNews
<
GetNewsResponseType
>
({
const
{
data
:
allData
,
isLoading
}
=
useGetNews
<
GetNewsResponseType
>
({
pageSize
:
String
(
pageSize
),
currentPage
:
String
(
page
),
filters
:
submitSearch
?
`title @=
${
submitSearch
}
`
:
'category @=Đào tạo'
,
...
...
@@ -28,19 +29,28 @@ export default function Page() {
{
/* Main content */
}
<
main
className=
"lg:col-span-2 bg-background "
>
<
div
className=
"pb-5 overflow-hidden"
>
{
allData
?.
responseData
.
rows
.
map
((
news
)
=>
(
<
NewsContent
key=
{
news
.
id
}
news=
{
news
}
link=
{
`${PATHS.event}/dao-tao/${news.id}`
}
/>
))
}
{
isLoading
?
(
<
div
className=
"flex justify-center items-center py-12"
>
<
Spinner
className=
"size-8"
/>
<
span
className=
"ml-2 text-gray-600"
>
Đang tải khóa đào tạo...
</
span
>
</
div
>
)
:
(
<>
{
allData
?.
responseData
.
rows
.
map
((
news
)
=>
(
<
NewsContent
key=
{
news
.
id
}
news=
{
news
}
link=
{
`${PATHS.event}/dao-tao/${news.id}`
}
/>
))
}
<
div
className=
"w-full flex justify-center mt-4"
>
<
Pagination
pageCount=
{
Number
(
allData
?.
responseData
.
totalPages
??
1
)
}
page=
{
Number
(
allData
?.
responseData
.
currentPage
??
page
)
}
onChangePage=
{
(
p
)
=>
setPage
(
p
)
}
onGoToPreviousPage=
{
()
=>
setPage
(
Math
.
max
(
1
,
page
-
1
))
}
onGoToNextPage=
{
()
=>
setPage
(
Math
.
min
(
Number
(
allData
?.
responseData
.
totalPages
??
1
),
page
+
1
))
}
/>
</
div
>
<
div
className=
"w-full flex justify-center mt-4"
>
<
Pagination
pageCount=
{
Number
(
allData
?.
responseData
.
totalPages
??
1
)
}
page=
{
Number
(
allData
?.
responseData
.
currentPage
??
page
)
}
onChangePage=
{
(
p
)
=>
setPage
(
p
)
}
onGoToPreviousPage=
{
()
=>
setPage
(
Math
.
max
(
1
,
page
-
1
))
}
onGoToNextPage=
{
()
=>
setPage
(
Math
.
min
(
Number
(
allData
?.
responseData
.
totalPages
??
1
),
page
+
1
))
}
/>
</
div
>
</>
)
}
</
div
>
</
main
>
...
...
src/app/(main)/hoat-dong/su-kien/[id]/page.tsx
View file @
74a04b88
...
...
@@ -4,14 +4,16 @@ import Image from "next/image";
import
ListCategory
from
"@app/dai-dien-gioi-chu/components/list-category"
;
import
{
EVENT_CATEGORIES
}
from
"@constants/categories"
;
import
ListFilter
from
"@app/dai-dien-gioi-chu/components/list-filter"
;
import
{
useGetNewsId
}
from
'@/api/endpoints/news
'
;
import
{
useGetEventsId
}
from
'@/api/endpoints/event
'
;
import
parse
from
"html-react-parser"
;
import
{
useParams
}
from
'next/navigation'
import
{
GetNewsDetailResponseType
}
from
'@lib/types/news-detail-response-data'
;
import
{
GetEventsIdQueryResponseType
}
from
'@api/types/event'
;
import
{
Spinner
}
from
"@components/ui/spinner"
;
// ...existing code...
const
Page
:
React
.
FC
=
()
=>
{
const
{
id
}
=
useParams
()
const
{
data
,
isLoading
}
=
useGet
NewsId
<
GetNewsDetail
ResponseType
>
(
id
as
string
)
const
{
data
,
isLoading
}
=
useGet
EventsId
<
GetEventsIdQuery
ResponseType
>
(
id
as
string
)
return
(
<
div
className=
"min-h-screen w-full container mx-auto p-4"
>
<
div
className=
"w-full flex flex-col gap-5"
>
...
...
@@ -20,11 +22,20 @@ const Page: React.FC = () => {
<
div
className=
"grid grid-cols-1 lg:grid-cols-3 gap-6"
>
{
/* Main content */
}
<
main
className=
"lg:col-span-2 bg-white border rounded-md p-6"
>
<
div
className=
'pb-5 text-primary text-2xl leading-normal font-medium'
>
{
data
?.
responseData
?.
title
}
{
isLoading
?
(
<
div
className=
"flex justify-center items-center py-12"
>
<
Spinner
className=
"size-8"
/>
<
span
className=
"ml-2 text-gray-600"
>
Đang tải chi tiết sự kiện...
</
span
>
</
div
>
)
:
(
<>
<
div
className=
'pb-5 text-primary text-2xl leading-normal font-medium'
>
{
data
?.
responseData
?.
name
}
</
div
>
<
hr
className=
"py-2"
/>
<
div
className=
"p-7.5 prose tiptap overflow-hidden"
>
{
parse
(
data
?.
responseData
?.
description
??
''
)
}
</
div
>
<
div
className=
"p-7.5 prose tiptap overflow-hidden"
>
{
parse
(
data
?.
responseData
?.
description
??
''
)
}
</
div
>
</>
)
}
</
main
>
{
/* Sidebar */
}
...
...
src/app/(main)/hoat-dong/su-kien/page.tsx
View file @
74a04b88
...
...
@@ -7,18 +7,23 @@ import NewsContent from "@app/dai-dien-gioi-chu/components/card-news";
// ...existing code...
import
{
Pagination
}
from
"@components/base/pagination"
;
import
Image
from
"next/image"
;
import
{
useGetEvents
}
from
'@api/endpoints/event'
import
{
EventApiResponse
}
from
'@api/types/event'
import
{
useGetNews
}
from
"@api/endpoints/news"
;
import
{
GetNewsResponseType
}
from
"@api/types/NewsPage.type"
;
import
{
PATHS
}
from
"@constants/paths"
;
import
{
Spinner
}
from
"@components/ui/spinner"
;
export
default
function
Page
()
{
const
[
submitSearch
]
=
useState
(
""
);
const
[
page
,
setPage
]
=
useState
(
1
);
const
pageSize
=
5
;
const
{
data
:
allData
}
=
useGetNews
<
GetNewsResponseTyp
e
>
({
const
{
data
:
allData
,
isLoading
}
=
useGetEvents
<
EventApiRespons
e
>
({
pageSize
:
String
(
pageSize
),
currentPage
:
String
(
page
),
filters
:
submitSearch
?
`title @=
${
submitSearch
}
`
:
'category @=Sự kiện'
,
sortField
:
'start_time'
,
sortOrder
:
'ASC'
,
filters
:
submitSearch
?
`title @=
${
submitSearch
}
,start_time>
${
new
Date
()}
`
:
`start_time>
${
new
Date
()}
`
,
});
return
(
<
div
className=
"min-h-screen container mx-auto p-4"
>
...
...
@@ -29,19 +34,28 @@ export default function Page() {
{
/* Main content */
}
<
main
className=
"lg:col-span-2 bg-background "
>
<
div
className=
"pb-5 overflow-hidden"
>
{
allData
?.
responseData
.
rows
.
map
((
news
)
=>
(
<
NewsContent
key=
{
news
.
id
}
news=
{
news
}
link=
{
`${PATHS.event}/su-kien/${news.id}`
}
/>
))
}
{
isLoading
?
(
<
div
className=
"flex justify-center items-center py-12"
>
<
Spinner
className=
"size-8"
/>
<
span
className=
"ml-2 text-gray-600"
>
Đang tải sự kiện...
</
span
>
</
div
>
)
:
(
<>
{
allData
?.
responseData
.
rows
.
map
((
event
)
=>
(
<
NewsContent
key=
{
event
.
id
}
event=
{
event
}
link=
{
`${PATHS.event}/su-kien/${event.id}`
}
/>
))
}
<
div
className=
"w-full flex justify-center mt-4"
>
<
Pagination
pageCount=
{
Number
(
allData
?.
responseData
.
totalPages
??
1
)
}
page=
{
Number
(
allData
?.
responseData
.
currentPage
??
page
)
}
onChangePage=
{
(
p
)
=>
setPage
(
p
)
}
onGoToPreviousPage=
{
()
=>
setPage
(
Math
.
max
(
1
,
page
-
1
))
}
onGoToNextPage=
{
()
=>
setPage
(
Math
.
min
(
Number
(
allData
?.
responseData
.
totalPages
??
1
),
page
+
1
))
}
/>
</
div
>
<
div
className=
"w-full flex justify-center mt-4"
>
<
Pagination
pageCount=
{
Number
(
allData
?.
responseData
.
totalPages
??
1
)
}
page=
{
Number
(
allData
?.
responseData
.
currentPage
??
page
)
}
onChangePage=
{
(
p
)
=>
setPage
(
p
)
}
onGoToPreviousPage=
{
()
=>
setPage
(
Math
.
max
(
1
,
page
-
1
))
}
onGoToNextPage=
{
()
=>
setPage
(
Math
.
min
(
Number
(
allData
?.
responseData
.
totalPages
??
1
),
page
+
1
))
}
/>
</
div
>
</>
)
}
</
div
>
</
main
>
...
...
src/app/(main)/hoi-vien/ket-noi-hoi-vien/page.tsx
View file @
74a04b88
...
...
@@ -7,6 +7,7 @@ import { Pagination } from "@components/base/pagination";
import
Image
from
"next/image"
;
import
{
useGetNews
}
from
"@api/endpoints/news"
;
import
{
GetNewsResponseType
}
from
"@api/types/NewsPage.type"
;
import
{
Spinner
}
from
"@components/ui/spinner"
;
export
default
function
Page
()
{
const
[
submitSearch
]
=
useState
(
""
);
...
...
@@ -26,26 +27,35 @@ export default function Page() {
{
/* Main content */
}
<
main
className=
"lg:col-span-2 bg-background"
>
<
div
className=
"pb-5 overflow-hidden"
>
{
allData
?.
responseData
.
rows
.
map
((
news
)
=>
(
<
CardNews
key=
{
news
.
id
}
news=
{
news
}
/>
))
}
{
isLoading
?
(
<
div
className=
"flex justify-center items-center py-12"
>
<
Spinner
className=
"size-8"
/>
<
span
className=
"ml-2 text-gray-600"
>
Đang tải dữ liệu kết nối hội viên...
</
span
>
</
div
>
)
:
(
<>
{
allData
?.
responseData
.
rows
.
map
((
news
)
=>
(
<
CardNews
key=
{
news
.
id
}
news=
{
news
}
/>
))
}
<
div
className=
'w-full flex justify-center mt-4'
>
<
Pagination
pageCount=
{
Number
(
allData
?.
responseData
.
totalPages
??
1
)
}
page=
{
Number
(
allData
?.
responseData
.
currentPage
??
page
)
}
onChangePage=
{
(
p
)
=>
setPage
(
p
)
}
onGoToPreviousPage=
{
()
=>
setPage
(
Math
.
max
(
1
,
page
-
1
))
}
onGoToNextPage=
{
()
=>
setPage
(
Math
.
min
(
Number
(
allData
?.
responseData
.
totalPages
??
1
),
page
+
1
)
)
}
/>
</
div
>
<
div
className=
'w-full flex justify-center mt-4'
>
<
Pagination
pageCount=
{
Number
(
allData
?.
responseData
.
totalPages
??
1
)
}
page=
{
Number
(
allData
?.
responseData
.
currentPage
??
page
)
}
onChangePage=
{
(
p
)
=>
setPage
(
p
)
}
onGoToPreviousPage=
{
()
=>
setPage
(
Math
.
max
(
1
,
page
-
1
))
}
onGoToNextPage=
{
()
=>
setPage
(
Math
.
min
(
Number
(
allData
?.
responseData
.
totalPages
??
1
),
page
+
1
)
)
}
/>
</
div
>
</>
)
}
</
div
>
</
main
>
...
...
src/app/(main)/hoi-vien/tin-hoi-vien/page.tsx
View file @
74a04b88
...
...
@@ -7,6 +7,7 @@ import { Pagination } from '@components/base/pagination'
import
Image
from
"next/image"
;
import
{
useGetNews
}
from
'@api/endpoints/news'
import
{
GetNewsResponseType
}
from
'@api/types/NewsPage.type'
import
{
Spinner
}
from
"@components/ui/spinner"
;
export
default
function
Page
()
{
const
[
submitSearch
]
=
useState
(
''
)
...
...
@@ -26,26 +27,35 @@ export default function Page() {
{
/* Main content */
}
<
main
className=
"lg:col-span-2 bg-background"
>
<
div
className=
'pb-5 overflow-hidden'
>
{
allData
?.
responseData
.
rows
.
map
((
news
)
=>
(
<
CardNews
key=
{
news
.
id
}
news=
{
news
}
/>
))
}
{
isLoading
?
(
<
div
className=
"flex justify-center items-center py-12"
>
<
Spinner
className=
"size-8"
/>
<
span
className=
"ml-2 text-gray-600"
>
Đang tải tin hội viên...
</
span
>
</
div
>
)
:
(
<>
{
allData
?.
responseData
.
rows
.
map
((
news
)
=>
(
<
CardNews
key=
{
news
.
id
}
news=
{
news
}
/>
))
}
<
div
className=
'w-full flex justify-center mt-4'
>
<
Pagination
pageCount=
{
Number
(
allData
?.
responseData
.
totalPages
??
1
)
}
page=
{
Number
(
allData
?.
responseData
.
currentPage
??
page
)
}
onChangePage=
{
(
p
)
=>
setPage
(
p
)
}
onGoToPreviousPage=
{
()
=>
setPage
(
Math
.
max
(
1
,
page
-
1
))
}
onGoToNextPage=
{
()
=>
setPage
(
Math
.
min
(
Number
(
allData
?.
responseData
.
totalPages
??
1
),
page
+
1
)
)
}
/>
</
div
>
<
div
className=
'w-full flex justify-center mt-4'
>
<
Pagination
pageCount=
{
Number
(
allData
?.
responseData
.
totalPages
??
1
)
}
page=
{
Number
(
allData
?.
responseData
.
currentPage
??
page
)
}
onChangePage=
{
(
p
)
=>
setPage
(
p
)
}
onGoToPreviousPage=
{
()
=>
setPage
(
Math
.
max
(
1
,
page
-
1
))
}
onGoToNextPage=
{
()
=>
setPage
(
Math
.
min
(
Number
(
allData
?.
responseData
.
totalPages
??
1
),
page
+
1
)
)
}
/>
</
div
>
</>
)
}
</
div
>
</
main
>
...
...
src/app/(main)/search/page.tsx
View file @
74a04b88
...
...
@@ -8,6 +8,7 @@ import { Pagination } from "@components/base/pagination";
import
Image
from
"next/image"
;
import
{
useGetNews
}
from
"@api/endpoints/news"
;
import
{
GetNewsResponseType
}
from
"@api/types/NewsPage.type"
;
import
{
Spinner
}
from
"@components/ui/spinner"
;
import
{
PATHS
}
from
"@constants/paths"
;
import
{
useSearchParams
}
from
'next/navigation'
...
...
@@ -16,7 +17,7 @@ function SearchContent() {
const
searchParams
=
useSearchParams
()
const
query
=
searchParams
.
get
(
'q'
)
//
const
pageSize
=
5
;
const
{
data
:
allData
}
=
useGetNews
<
GetNewsResponseType
>
({
const
{
data
:
allData
,
isLoading
}
=
useGetNews
<
GetNewsResponseType
>
({
pageSize
:
String
(
pageSize
),
currentPage
:
String
(
page
),
filters
:
query
?
`title @=
${
query
}
`
:
undefined
,
...
...
@@ -40,30 +41,39 @@ function SearchContent() {
{
/* Main content */
}
<
main
className=
"lg:col-span-2 bg-background "
>
<
div
className=
"pb-5 overflow-hidden"
>
{
allData
?.
responseData
.
rows
.
map
((
news
)
=>
(
<
NewsContent
key=
{
news
.
id
}
news=
{
news
}
link=
{
`${PATHS.mediaInformation}/tin-vcci/${news.id}`
}
/>
))
}
{
isLoading
?
(
<
div
className=
"flex justify-center items-center py-12"
>
<
Spinner
className=
"size-8"
/>
<
span
className=
"ml-2 text-gray-600"
>
Đang tìm kiếm...
</
span
>
</
div
>
)
:
(
<>
{
allData
?.
responseData
.
rows
.
map
((
news
)
=>
(
<
NewsContent
key=
{
news
.
id
}
news=
{
news
}
link=
{
`${PATHS.mediaInformation}/tin-vcci/${news.id}`
}
/>
))
}
<
div
className=
"w-full flex justify-center mt-4"
>
<
Pagination
pageCount=
{
Number
(
allData
?.
responseData
.
totalPages
??
1
)
}
page=
{
Number
(
allData
?.
responseData
.
currentPage
??
page
)
}
onChangePage=
{
(
p
)
=>
setPage
(
p
)
}
onGoToPreviousPage=
{
()
=>
setPage
(
Math
.
max
(
1
,
page
-
1
))
}
onGoToNextPage=
{
()
=>
setPage
(
Math
.
min
(
Number
(
allData
?.
responseData
.
totalPages
??
1
),
page
+
1
)
)
}
/>
</
div
>
<
div
className=
"w-full flex justify-center mt-4"
>
<
Pagination
pageCount=
{
Number
(
allData
?.
responseData
.
totalPages
??
1
)
}
page=
{
Number
(
allData
?.
responseData
.
currentPage
??
page
)
}
onChangePage=
{
(
p
)
=>
setPage
(
p
)
}
onGoToPreviousPage=
{
()
=>
setPage
(
Math
.
max
(
1
,
page
-
1
))
}
onGoToNextPage=
{
()
=>
setPage
(
Math
.
min
(
Number
(
allData
?.
responseData
.
totalPages
??
1
),
page
+
1
)
)
}
/>
</
div
>
</>
)
}
</
div
>
</
main
>
...
...
src/app/(main)/thong-tin-truyen-thong/chuyen-de/page.tsx
View file @
74a04b88
...
...
@@ -10,14 +10,15 @@ import Image from "next/image";
import
{
useGetNews
}
from
"@api/endpoints/news"
;
import
{
GetNewsResponseType
}
from
"@api/types/NewsPage.type"
;
import
{
PATHS
}
from
"@constants/paths"
;
import
{
Spinner
}
from
"@components/ui/spinner"
;
export
default
function
Page
()
{
const
[
submitSearch
]
=
useState
(
""
);
const
[
page
,
setPage
]
=
useState
(
1
);
const
pageSize
=
5
;
const
{
data
:
allData
}
=
useGetNews
<
GetNewsResponseType
>
({
const
{
data
:
allData
,
isLoading
}
=
useGetNews
<
GetNewsResponseType
>
({
pageSize
:
String
(
pageSize
),
currentPage
:
String
(
page
),
filters
:
submitSearch
?
`title @=
${
submitSearch
}
`
:
'category @=Chuyên đề'
,
filters
:
submitSearch
?
`title @=
${
submitSearch
}
,category @=Chuyên đề
`
:
'category @=Chuyên đề'
,
});
return
(
<
div
className=
"min-h-screen container mx-auto p-4"
>
...
...
@@ -28,26 +29,34 @@ export default function Page() {
{
/* Main content */
}
<
main
className=
"lg:col-span-2 bg-background "
>
<
div
className=
"pb-5 overflow-hidden"
>
{
allData
?.
responseData
.
rows
.
length
===
0
?
(
{
isLoading
?
(
<
div
className=
"flex justify-center items-center py-12"
>
<
Spinner
className=
"size-8"
/>
<
span
className=
"ml-2 text-gray-600"
>
Đang tải chuyên đề...
</
span
>
</
div
>
)
:
allData
?.
responseData
.
rows
.
length
===
0
?
(
<
p
className=
"text-center py-4"
>
Không có dữ liệu
</
p
>
)
:
(
allData
?.
responseData
.
rows
.
map
((
news
)
=>
(
<
NewsContent
key=
{
news
.
id
}
news=
{
news
}
link=
{
`${PATHS.mediaInformation}/chuyen-de/${news.id}`
}
/>
)))
}
<>
{
allData
?.
responseData
.
rows
.
map
((
news
)
=>
(
<
NewsContent
key=
{
news
.
id
}
news=
{
news
}
link=
{
`${PATHS.mediaInformation}/chuyen-de/${news.id}`
}
/>
))
}
<
div
className=
"w-full flex justify-center mt-4"
>
<
Pagination
pageCount=
{
Number
(
allData
?.
responseData
.
totalPages
??
1
)
}
page=
{
Number
(
allData
?.
responseData
.
currentPage
??
page
)
}
onChangePage=
{
(
p
)
=>
setPage
(
p
)
}
onGoToPreviousPage=
{
()
=>
setPage
(
Math
.
max
(
1
,
page
-
1
))
}
onGoToNextPage=
{
()
=>
setPage
(
Math
.
min
(
Number
(
allData
?.
responseData
.
totalPages
??
1
),
page
+
1
))
}
/>
</
div
>
<
div
className=
"w-full flex justify-center mt-4"
>
<
Pagination
pageCount=
{
Number
(
allData
?.
responseData
.
totalPages
??
1
)
}
page=
{
Number
(
allData
?.
responseData
.
currentPage
??
page
)
}
onChangePage=
{
(
p
)
=>
setPage
(
p
)
}
onGoToPreviousPage=
{
()
=>
setPage
(
Math
.
max
(
1
,
page
-
1
))
}
onGoToNextPage=
{
()
=>
setPage
(
Math
.
min
(
Number
(
allData
?.
responseData
.
totalPages
??
1
),
page
+
1
))
}
/>
</
div
>
</>
)
}
</
div
>
</
main
>
...
...
src/app/(main)/thong-tin-truyen-thong/thong-tin-chinh-sach-va-phap-luat/page.tsx
View file @
74a04b88
...
...
@@ -15,10 +15,10 @@ export default function Page() {
const
[
page
,
setPage
]
=
useState
(
1
);
const
pageSize
=
5
;
const
{
data
:
allData
}
=
useGetNews
<
GetNewsResponseType
>
({
const
{
data
:
allData
,
isLoading
}
=
useGetNews
<
GetNewsResponseType
>
({
pageSize
:
String
(
pageSize
),
currentPage
:
String
(
page
),
filters
:
submitSearch
?
`title @=
${
submitSearch
}
`
:
'category @=Thông tin chính sách và pháp luật'
,
filters
:
submitSearch
?
`title @=
${
submitSearch
}
,category @=Thông tin chính sách và pháp luật
`
:
'category @=Thông tin chính sách và pháp luật'
,
});
return
(
<
div
className=
"min-h-screen container mx-auto p-4"
>
...
...
src/app/(main)/thong-tin-truyen-thong/thu-vien-tai-lieu/page.tsx
View file @
74a04b88
...
...
@@ -10,15 +10,16 @@ import Image from "next/image";
import
{
useGetNews
}
from
"@api/endpoints/news"
;
import
{
GetNewsResponseType
}
from
"@api/types/NewsPage.type"
;
import
{
PATHS
}
from
"@constants/paths"
;
import
{
Spinner
}
from
"@components/ui/spinner"
;
export
default
function
Page
()
{
const
[
submitSearch
]
=
useState
(
""
);
const
[
page
,
setPage
]
=
useState
(
1
);
const
pageSize
=
5
;
const
{
data
:
allData
}
=
useGetNews
<
GetNewsResponseType
>
({
const
{
data
:
allData
,
isLoading
}
=
useGetNews
<
GetNewsResponseType
>
({
pageSize
:
String
(
pageSize
),
currentPage
:
String
(
page
),
filters
:
submitSearch
?
`title @=
${
submitSearch
}
`
:
'category @=Thư viện tài liệu'
,
filters
:
submitSearch
?
`title @=
${
submitSearch
}
,category @=Thư viện tài liệu'
`
:
'category @=Thư viện tài liệu'
,
});
return
(
<
div
className=
"min-h-screen container mx-auto p-4"
>
...
...
@@ -29,26 +30,34 @@ export default function Page() {
{
/* Main content */
}
<
main
className=
"lg:col-span-2 bg-background "
>
<
div
className=
"pb-5 overflow-hidden"
>
{
allData
?.
responseData
.
rows
.
length
===
0
?
(
{
isLoading
?
(
<
div
className=
"flex justify-center items-center py-12"
>
<
Spinner
className=
"size-8"
/>
<
span
className=
"ml-2 text-gray-600"
>
Đang tải thư viện tài liệu...
</
span
>
</
div
>
)
:
allData
?.
responseData
.
rows
.
length
===
0
?
(
<
p
className=
"text-center py-4"
>
Không có dữ liệu
</
p
>
)
:
(
allData
?.
responseData
.
rows
.
map
((
news
)
=>
(
<
NewsContent
key=
{
news
.
id
}
news=
{
news
}
link=
{
`${PATHS.mediaInformation}/thu-vien-tai-lieu/${news.id}`
}
/>
)))
}
<>
{
allData
?.
responseData
.
rows
.
map
((
news
)
=>
(
<
NewsContent
key=
{
news
.
id
}
news=
{
news
}
link=
{
`${PATHS.mediaInformation}/thu-vien-tai-lieu/${news.id}`
}
/>
))
}
<
div
className=
"w-full flex justify-center mt-4"
>
<
Pagination
pageCount=
{
Number
(
allData
?.
responseData
.
totalPages
??
1
)
}
page=
{
Number
(
allData
?.
responseData
.
currentPage
??
page
)
}
onChangePage=
{
(
p
)
=>
setPage
(
p
)
}
onGoToPreviousPage=
{
()
=>
setPage
(
Math
.
max
(
1
,
page
-
1
))
}
onGoToNextPage=
{
()
=>
setPage
(
Math
.
min
(
Number
(
allData
?.
responseData
.
totalPages
??
1
),
page
+
1
))
}
/>
</
div
>
<
div
className=
"w-full flex justify-center mt-4"
>
<
Pagination
pageCount=
{
Number
(
allData
?.
responseData
.
totalPages
??
1
)
}
page=
{
Number
(
allData
?.
responseData
.
currentPage
??
page
)
}
onChangePage=
{
(
p
)
=>
setPage
(
p
)
}
onGoToPreviousPage=
{
()
=>
setPage
(
Math
.
max
(
1
,
page
-
1
))
}
onGoToNextPage=
{
()
=>
setPage
(
Math
.
min
(
Number
(
allData
?.
responseData
.
totalPages
??
1
),
page
+
1
))
}
/>
</
div
>
</>
)
}
</
div
>
</
main
>
...
...
src/app/(main)/thong-tin-truyen-thong/tin-doanh-nghiep/page.tsx
View file @
74a04b88
...
...
@@ -10,15 +10,16 @@ import Image from "next/image";
import
{
useGetNews
}
from
"@api/endpoints/news"
;
import
{
GetNewsResponseType
}
from
"@api/types/NewsPage.type"
;
import
{
PATHS
}
from
"@constants/paths"
;
import
{
Spinner
}
from
"@components/ui/spinner"
;
export
default
function
Page
()
{
const
[
submitSearch
]
=
useState
(
""
);
const
[
page
,
setPage
]
=
useState
(
1
);
const
pageSize
=
5
;
const
{
data
:
allData
}
=
useGetNews
<
GetNewsResponseType
>
({
const
{
data
:
allData
,
isLoading
}
=
useGetNews
<
GetNewsResponseType
>
({
pageSize
:
String
(
pageSize
),
currentPage
:
String
(
page
),
filters
:
submitSearch
?
`title @=
${
submitSearch
}
`
:
'category @=Tin doanh nghiệp'
,
filters
:
submitSearch
?
`title @=
${
submitSearch
}
,category @=Tin doanh nghiệp
`
:
'category @=Tin doanh nghiệp'
,
});
return
(
<
div
className=
"min-h-screen container mx-auto p-4"
>
...
...
@@ -29,26 +30,34 @@ export default function Page() {
{
/* Main content */
}
<
main
className=
"lg:col-span-2 bg-background "
>
<
div
className=
"pb-5 overflow-hidden"
>
{
allData
?.
responseData
.
rows
.
length
===
0
?
(
{
isLoading
?
(
<
div
className=
"flex justify-center items-center py-12"
>
<
Spinner
className=
"size-8"
/>
<
span
className=
"ml-2 text-gray-600"
>
Đang tải tin doanh nghiệp...
</
span
>
</
div
>
)
:
allData
?.
responseData
.
rows
.
length
===
0
?
(
<
p
className=
"text-center py-4"
>
Không có dữ liệu
</
p
>
)
:
(
allData
?.
responseData
.
rows
.
map
((
news
)
=>
(
<
NewsContent
key=
{
news
.
id
}
news=
{
news
}
link=
{
`${PATHS.mediaInformation}/tin-doanh-nghiep/${news.id}`
}
/>
)))
}
<>
{
allData
?.
responseData
.
rows
.
map
((
news
)
=>
(
<
NewsContent
key=
{
news
.
id
}
news=
{
news
}
link=
{
`${PATHS.mediaInformation}/tin-doanh-nghiep/${news.id}`
}
/>
))
}
<
div
className=
"w-full flex justify-center mt-4"
>
<
Pagination
pageCount=
{
Number
(
allData
?.
responseData
.
totalPages
??
1
)
}
page=
{
Number
(
allData
?.
responseData
.
currentPage
??
page
)
}
onChangePage=
{
(
p
)
=>
setPage
(
p
)
}
onGoToPreviousPage=
{
()
=>
setPage
(
Math
.
max
(
1
,
page
-
1
))
}
onGoToNextPage=
{
()
=>
setPage
(
Math
.
min
(
Number
(
allData
?.
responseData
.
totalPages
??
1
),
page
+
1
))
}
/>
</
div
>
<
div
className=
"w-full flex justify-center mt-4"
>
<
Pagination
pageCount=
{
Number
(
allData
?.
responseData
.
totalPages
??
1
)
}
page=
{
Number
(
allData
?.
responseData
.
currentPage
??
page
)
}
onChangePage=
{
(
p
)
=>
setPage
(
p
)
}
onGoToPreviousPage=
{
()
=>
setPage
(
Math
.
max
(
1
,
page
-
1
))
}
onGoToNextPage=
{
()
=>
setPage
(
Math
.
min
(
Number
(
allData
?.
responseData
.
totalPages
??
1
),
page
+
1
))
}
/>
</
div
>
</>
)
}
</
div
>
</
main
>
...
...
src/app/(main)/thong-tin-truyen-thong/tin-kinh-te/page.tsx
View file @
74a04b88
...
...
@@ -9,15 +9,16 @@ import Image from "next/image";
import
{
useGetNews
}
from
"@api/endpoints/news"
;
import
{
GetNewsResponseType
}
from
"@api/types/NewsPage.type"
;
import
{
PATHS
}
from
"@constants/paths"
;
import
{
Spinner
}
from
"@components/ui/spinner"
;
export
default
function
Page
()
{
const
[
submitSearch
]
=
useState
(
""
);
const
[
page
,
setPage
]
=
useState
(
1
);
const
pageSize
=
5
;
const
{
data
:
allData
}
=
useGetNews
<
GetNewsResponseType
>
({
const
{
data
:
allData
,
isLoading
}
=
useGetNews
<
GetNewsResponseType
>
({
pageSize
:
String
(
pageSize
),
currentPage
:
String
(
page
),
filters
:
submitSearch
?
`title @=
${
submitSearch
}
`
:
'category @=Tin kinh tế'
,
filters
:
submitSearch
?
`title @=
${
submitSearch
}
,category @=Tin kinh tế
`
:
'category @=Tin kinh tế'
,
});
return
(
<
div
className=
"min-h-screen container mx-auto p-4"
>
...
...
@@ -28,26 +29,34 @@ export default function Page() {
{
/* Main content */
}
<
main
className=
"lg:col-span-2 bg-background "
>
<
div
className=
"pb-5 overflow-hidden"
>
{
allData
?.
responseData
.
rows
.
length
===
0
?
(
{
isLoading
?
(
<
div
className=
"flex justify-center items-center py-12"
>
<
Spinner
className=
"size-8"
/>
<
span
className=
"ml-2 text-gray-600"
>
Đang tải tin kinh tế...
</
span
>
</
div
>
)
:
allData
?.
responseData
.
rows
.
length
===
0
?
(
<
p
className=
"text-center py-4"
>
Không có dữ liệu
</
p
>
)
:
(
allData
?.
responseData
.
rows
.
map
((
news
)
=>
(
<
NewsContent
key=
{
news
.
id
}
news=
{
news
}
link=
{
`${PATHS.mediaInformation}/tin-kinh-te/${news.id}`
}
/>
)))
}
<>
{
allData
?.
responseData
.
rows
.
map
((
news
)
=>
(
<
NewsContent
key=
{
news
.
id
}
news=
{
news
}
link=
{
`${PATHS.mediaInformation}/tin-kinh-te/${news.id}`
}
/>
))
}
<
div
className=
"w-full flex justify-center mt-4"
>
<
Pagination
pageCount=
{
Number
(
allData
?.
responseData
.
totalPages
??
1
)
}
page=
{
Number
(
allData
?.
responseData
.
currentPage
??
page
)
}
onChangePage=
{
(
p
)
=>
setPage
(
p
)
}
onGoToPreviousPage=
{
()
=>
setPage
(
Math
.
max
(
1
,
page
-
1
))
}
onGoToNextPage=
{
()
=>
setPage
(
Math
.
min
(
Number
(
allData
?.
responseData
.
totalPages
??
1
),
page
+
1
))
}
/>
</
div
>
<
div
className=
"w-full flex justify-center mt-4"
>
<
Pagination
pageCount=
{
Number
(
allData
?.
responseData
.
totalPages
??
1
)
}
page=
{
Number
(
allData
?.
responseData
.
currentPage
??
page
)
}
onChangePage=
{
(
p
)
=>
setPage
(
p
)
}
onGoToPreviousPage=
{
()
=>
setPage
(
Math
.
max
(
1
,
page
-
1
))
}
onGoToNextPage=
{
()
=>
setPage
(
Math
.
min
(
Number
(
allData
?.
responseData
.
totalPages
??
1
),
page
+
1
))
}
/>
</
div
>
</>
)
}
</
div
>
</
main
>
...
...
src/app/(main)/thong-tin-truyen-thong/tin-vcci/page.tsx
View file @
74a04b88
...
...
@@ -11,12 +11,13 @@ import Image from "next/image";
import
{
useGetNews
}
from
"@api/endpoints/news"
;
import
{
PATHS
}
from
"@constants/paths"
;
import
{
GetNewsResponseType
}
from
"@api/types/NewsPage.type"
;
import
{
Spinner
}
from
"@components/ui/spinner"
;
export
default
function
Page
()
{
const
[
submitSearch
,
setSubmitSearch
]
=
useState
(
""
);
const
[
page
,
setPage
]
=
useState
(
1
);
const
pageSize
=
5
;
const
{
data
:
allData
}
=
useGetNews
<
GetNewsResponseType
>
({
const
{
data
:
allData
,
isLoading
}
=
useGetNews
<
GetNewsResponseType
>
({
pageSize
:
String
(
pageSize
),
currentPage
:
String
(
page
),
filters
:
submitSearch
?
`title @=
${
submitSearch
}
`
:
undefined
,
...
...
@@ -30,27 +31,34 @@ export default function Page() {
{
/* Main content */
}
<
main
className=
"lg:col-span-2 bg-background "
>
<
div
className=
"pb-5 overflow-hidden"
>
{
allData
?.
responseData
.
rows
.
length
===
0
?
(
{
isLoading
?
(
<
div
className=
"flex justify-center items-center py-12"
>
<
Spinner
className=
"size-8"
/>
<
span
className=
"ml-2 text-gray-600"
>
Đang tải tin VCCI...
</
span
>
</
div
>
)
:
allData
?.
responseData
.
rows
.
length
===
0
?
(
<
p
className=
"text-center py-4"
>
Không có dữ liệu
</
p
>
)
:
(
allData
?.
responseData
.
rows
.
map
((
news
)
=>
(
<
NewsContent
key=
{
news
.
id
}
news=
{
news
}
link=
{
`${PATHS.mediaInformation}/tin-vcci/${news.id}`
}
/>
)))
}
<>
{
allData
?.
responseData
.
rows
.
map
((
news
)
=>
(
<
NewsContent
key=
{
news
.
id
}
news=
{
news
}
link=
{
`${PATHS.mediaInformation}/tin-vcci/${news.id}`
}
/>
))
}
<
div
className=
"w-full flex justify-center mt-4"
>
<
Pagination
pageCount=
{
Number
(
allData
?.
responseData
.
totalPages
??
1
)
}
page=
{
Number
(
allData
?.
responseData
.
currentPage
??
page
)
}
onChangePage=
{
(
p
)
=>
setPage
(
p
)
}
onGoToPreviousPage=
{
()
=>
setPage
(
Math
.
max
(
1
,
page
-
1
))
}
onGoToNextPage=
{
()
=>
setPage
(
Math
.
min
(
Number
(
allData
?.
responseData
.
totalPages
??
1
),
page
+
1
))
}
/>
</
div
>
<
div
className=
"w-full flex justify-center mt-4"
>
<
Pagination
pageCount=
{
Number
(
allData
?.
responseData
.
totalPages
??
1
)
}
page=
{
Number
(
allData
?.
responseData
.
currentPage
??
page
)
}
onChangePage=
{
(
p
)
=>
setPage
(
p
)
}
onGoToPreviousPage=
{
()
=>
setPage
(
Math
.
max
(
1
,
page
-
1
))
}
onGoToNextPage=
{
()
=>
setPage
(
Math
.
min
(
Number
(
allData
?.
responseData
.
totalPages
??
1
),
page
+
1
))
}
/>
</
div
>
</>
)
}
</
div
>
</
main
>
...
...
src/app/(main)/xuc-tien-thuong-mai/[id]/page.tsx
View file @
74a04b88
...
...
@@ -8,6 +8,7 @@ import { useGetNewsId } from '@/api/endpoints/news';
import
parse
from
"html-react-parser"
;
import
{
useParams
}
from
'next/navigation'
import
{
GetNewsDetailResponseType
}
from
'@lib/types/news-detail-response-data'
;
import
{
Spinner
}
from
"@components/ui/spinner"
;
// ...existing code...
const
Page
:
React
.
FC
=
()
=>
{
const
{
id
}
=
useParams
()
...
...
@@ -20,11 +21,20 @@ const Page: React.FC = () => {
<
div
className=
"grid grid-cols-1 lg:grid-cols-3 gap-6"
>
{
/* Main content */
}
<
main
className=
"lg:col-span-2 bg-white border rounded-md p-6"
>
<
div
className=
'pb-5 text-primary text-2xl leading-normal font-medium'
>
{
isLoading
?
(
<
div
className=
"flex justify-center items-center py-12"
>
<
Spinner
className=
"size-8"
/>
<
span
className=
"ml-2 text-gray-600"
>
Đang tải nội dung...
</
span
>
</
div
>
)
:
(
<>
<
div
className=
'pb-5 text-primary text-2xl leading-normal font-medium'
>
{
data
?.
responseData
?.
title
}
</
div
>
<
hr
className=
"py-2"
/>
<
div
className=
"p-7.5 prose tiptap overflow-hidden"
>
{
parse
(
data
?.
responseData
?.
description
??
''
)
}
</
div
>
<
div
className=
"p-7.5 prose tiptap overflow-hidden"
>
{
parse
(
data
?.
responseData
?.
description
??
''
)
}
</
div
>
</>
)
}
</
main
>
{
/* Sidebar */
}
...
...
src/app/(main)/xuc-tien-thuong-mai/co-hoi-kinh-doanh/[id]/page.tsx
View file @
74a04b88
...
...
@@ -8,6 +8,7 @@ import { useGetNewsId } from '@/api/endpoints/news';
import
parse
from
"html-react-parser"
;
import
{
useParams
}
from
'next/navigation'
import
{
GetNewsDetailResponseType
}
from
'@lib/types/news-detail-response-data'
;
import
{
Spinner
}
from
"@components/ui/spinner"
;
// ...existing code...
const
Page
:
React
.
FC
=
()
=>
{
const
{
id
}
=
useParams
()
...
...
@@ -20,11 +21,22 @@ const Page: React.FC = () => {
<
div
className=
"grid grid-cols-1 lg:grid-cols-3 gap-6"
>
{
/* Main content */
}
<
main
className=
"lg:col-span-2 bg-white border rounded-md p-6"
>
<
div
className=
'pb-5 text-primary text-2xl leading-normal font-medium'
>
{
isLoading
?
(
<
div
className=
"flex justify-center items-center py-12"
>
<
Spinner
className=
"size-8"
/>
<
span
className=
"ml-2 text-gray-600"
>
Đang tải chi tiết cơ hội kinh doanh...
</
span
>
</
div
>
)
:
data
?.
responseData
?
(
<>
<
div
className=
'pb-5 text-primary text-2xl leading-normal font-medium'
>
{
data
?.
responseData
?.
title
}
</
div
>
<
hr
className=
"py-2"
/>
<
div
className=
"p-7.5 prose tiptap overflow-hidden"
>
{
parse
(
data
?.
responseData
?.
description
??
''
)
}
</
div
>
<
div
className=
"p-7.5 prose tiptap overflow-hidden"
>
{
parse
(
data
?.
responseData
?.
description
??
''
)
}
</
div
>
</>
)
:
(
<
p
className=
"text-center py-4"
>
Không có dữ liệu
</
p
>
)
}
</
main
>
{
/* Sidebar */
}
...
...
src/app/(main)/xuc-tien-thuong-mai/co-hoi-kinh-doanh/page.tsx
View file @
74a04b88
...
...
@@ -9,12 +9,13 @@ import Image from "next/image";
import
{
useGetNews
}
from
"@api/endpoints/news"
;
import
{
GetNewsResponseType
}
from
"@api/types/NewsPage.type"
;
import
{
PATHS
}
from
"@constants/paths"
;
import
{
Spinner
}
from
"@components/ui/spinner"
;
export
default
function
Page
()
{
const
[
submitSearch
]
=
useState
(
""
);
const
[
page
,
setPage
]
=
useState
(
1
);
const
pageSize
=
5
;
const
{
data
:
allData
}
=
useGetNews
<
GetNewsResponseType
>
({
const
{
data
:
allData
,
isLoading
}
=
useGetNews
<
GetNewsResponseType
>
({
pageSize
:
String
(
pageSize
),
currentPage
:
String
(
page
),
// filters: submitSearch ? `title @=${submitSearch}` : undefined,
...
...
@@ -29,26 +30,37 @@ export default function Page() {
{
/* Main content */
}
<
main
className=
"lg:col-span-2 bg-background "
>
<
div
className=
"pb-5 overflow-hidden"
>
{
allData
?.
responseData
.
rows
.
map
((
news
)
=>
(
<
NewsContent
key=
{
news
.
id
}
news=
{
news
}
link=
{
`${PATHS.tradePromotion}/${news.id}`
}
/>
))
}
{
isLoading
?
(
<
div
className=
"flex justify-center items-center py-12"
>
<
Spinner
className=
"size-8"
/>
<
span
className=
"ml-2 text-gray-600"
>
Đang tải cơ hội kinh doanh...
</
span
>
</
div
>
)
:
allData
?.
responseData
.
rows
.
length
===
0
?
(
<
p
className=
"text-center py-4"
>
Không có dữ liệu
</
p
>
)
:
(
<>
{
allData
?.
responseData
.
rows
.
map
((
news
)
=>
(
<
NewsContent
key=
{
news
.
id
}
news=
{
news
}
link=
{
`${PATHS.tradePromotion}/${news.id}`
}
/>
))
}
<
div
className=
"w-full flex justify-center mt-4"
>
<
Pagination
pageCount=
{
Number
(
allData
?.
responseData
.
totalPages
??
1
)
}
page=
{
Number
(
allData
?.
responseData
.
currentPage
??
page
)
}
onChangePage=
{
(
p
)
=>
setPage
(
p
)
}
onGoToPreviousPage=
{
()
=>
setPage
(
Math
.
max
(
1
,
page
-
1
))
}
onGoToNextPage=
{
()
=>
setPage
(
Math
.
min
(
Number
(
allData
?.
responseData
.
totalPages
??
1
),
page
+
1
)
)
}
/>
</
div
>
<
div
className=
"w-full flex justify-center mt-4"
>
<
Pagination
pageCount=
{
Number
(
allData
?.
responseData
.
totalPages
??
1
)
}
page=
{
Number
(
allData
?.
responseData
.
currentPage
??
page
)
}
onChangePage=
{
(
p
)
=>
setPage
(
p
)
}
onGoToPreviousPage=
{
()
=>
setPage
(
Math
.
max
(
1
,
page
-
1
))
}
onGoToNextPage=
{
()
=>
setPage
(
Math
.
min
(
Number
(
allData
?.
responseData
.
totalPages
??
1
),
page
+
1
)
)
}
/>
</
div
>
</>
)
}
</
div
>
</
main
>
...
...
src/app/(main)/xuc-tien-thuong-mai/ho-tro-kinh-doanh/[id]/page.tsx
View file @
74a04b88
...
...
@@ -8,6 +8,7 @@ import { useGetNewsId } from '@/api/endpoints/news';
import
parse
from
"html-react-parser"
;
import
{
useParams
}
from
'next/navigation'
import
{
GetNewsDetailResponseType
}
from
'@lib/types/news-detail-response-data'
;
import
{
Spinner
}
from
"@components/ui/spinner"
;
// ...existing code...
const
Page
:
React
.
FC
=
()
=>
{
const
{
id
}
=
useParams
()
...
...
@@ -20,11 +21,22 @@ const Page: React.FC = () => {
<
div
className=
"grid grid-cols-1 lg:grid-cols-3 gap-6"
>
{
/* Main content */
}
<
main
className=
"lg:col-span-2 bg-white border rounded-md p-6"
>
<
div
className=
'pb-5 text-primary text-2xl leading-normal font-medium'
>
{
isLoading
?
(
<
div
className=
"flex justify-center items-center py-12"
>
<
Spinner
className=
"size-8"
/>
<
span
className=
"ml-2 text-gray-600"
>
Đang tải chi tiết hỗ trợ kinh doanh...
</
span
>
</
div
>
)
:
data
?.
responseData
?
(
<>
<
div
className=
'pb-5 text-primary text-2xl leading-normal font-medium'
>
{
data
?.
responseData
?.
title
}
</
div
>
<
hr
className=
"py-2"
/>
<
div
className=
"p-7.5 prose tiptap overflow-hidden"
>
{
parse
(
data
?.
responseData
?.
description
??
''
)
}
</
div
>
<
div
className=
"p-7.5 prose tiptap overflow-hidden"
>
{
parse
(
data
?.
responseData
?.
description
??
''
)
}
</
div
>
</>
)
:
(
<
p
className=
"text-center py-4"
>
Không có dữ liệu
</
p
>
)
}
</
main
>
{
/* Sidebar */
}
...
...
src/app/(main)/xuc-tien-thuong-mai/ho-tro-kinh-doanh/page.tsx
View file @
74a04b88
...
...
@@ -8,12 +8,13 @@ import Image from "next/image";
import
{
useGetNews
}
from
"@api/endpoints/news"
;
import
{
GetNewsResponseType
}
from
"@api/types/NewsPage.type"
;
import
{
PATHS
}
from
"@constants/paths"
;
import
{
Spinner
}
from
"@components/ui/spinner"
;
export
default
function
Page
()
{
const
[
submitSearch
]
=
useState
(
""
);
const
[
page
,
setPage
]
=
useState
(
1
);
const
pageSize
=
5
;
const
{
data
:
allData
}
=
useGetNews
<
GetNewsResponseType
>
({
const
{
data
:
allData
,
isLoading
}
=
useGetNews
<
GetNewsResponseType
>
({
pageSize
:
String
(
pageSize
),
currentPage
:
String
(
page
),
// filters: submitSearch ? `title @=${submitSearch}` : undefined,
...
...
@@ -28,30 +29,41 @@ export default function Page() {
{
/* Main content */
}
<
main
className=
"lg:col-span-2 bg-background "
>
<
div
className=
"pb-5 overflow-hidden"
>
{
allData
?.
responseData
.
rows
.
map
((
news
)
=>
(
<
NewsContent
key=
{
news
.
id
}
news=
{
news
}
link=
{
`${PATHS.tradePromotion}/${news.id}`
}
/>
))
}
{
isLoading
?
(
<
div
className=
"flex justify-center items-center py-12"
>
<
Spinner
className=
"size-8"
/>
<
span
className=
"ml-2 text-gray-600"
>
Đang tải hỗ trợ kinh doanh...
</
span
>
</
div
>
)
:
allData
?.
responseData
.
rows
.
length
===
0
?
(
<
p
className=
"text-center py-4"
>
Không có dữ liệu
</
p
>
)
:
(
<>
{
allData
?.
responseData
.
rows
.
map
((
news
)
=>
(
<
NewsContent
key=
{
news
.
id
}
news=
{
news
}
link=
{
`${PATHS.tradePromotion}/${news.id}`
}
/>
))
}
<
div
className=
"w-full flex justify-center mt-4"
>
<
Pagination
pageCount=
{
Number
(
allData
?.
responseData
.
totalPages
??
1
)
}
page=
{
Number
(
allData
?.
responseData
.
currentPage
??
page
)
}
onChangePage=
{
(
p
)
=>
setPage
(
p
)
}
onGoToPreviousPage=
{
()
=>
setPage
(
Math
.
max
(
1
,
page
-
1
))
}
onGoToNextPage=
{
()
=>
setPage
(
Math
.
min
(
Number
(
allData
?.
responseData
.
totalPages
??
1
),
page
+
1
)
)
}
/>
</
div
>
<
div
className=
"w-full flex justify-center mt-4"
>
<
Pagination
pageCount=
{
Number
(
allData
?.
responseData
.
totalPages
??
1
)
}
page=
{
Number
(
allData
?.
responseData
.
currentPage
??
page
)
}
onChangePage=
{
(
p
)
=>
setPage
(
p
)
}
onGoToPreviousPage=
{
()
=>
setPage
(
Math
.
max
(
1
,
page
-
1
))
}
onGoToNextPage=
{
()
=>
setPage
(
Math
.
min
(
Number
(
allData
?.
responseData
.
totalPages
??
1
),
page
+
1
)
)
}
/>
</
div
>
</>
)
}
</
div
>
</
main
>
...
...
src/app/(main)/xuc-tien-thuong-mai/moi-truong-kinh-doanh/[id]/page.tsx
View file @
74a04b88
...
...
@@ -8,6 +8,7 @@ import { useGetNewsId } from '@/api/endpoints/news';
import
parse
from
"html-react-parser"
;
import
{
useParams
}
from
'next/navigation'
import
{
GetNewsDetailResponseType
}
from
'@lib/types/news-detail-response-data'
;
import
{
Spinner
}
from
"@components/ui/spinner"
;
// ...existing code...
const
Page
:
React
.
FC
=
()
=>
{
const
{
id
}
=
useParams
()
...
...
@@ -20,11 +21,22 @@ const Page: React.FC = () => {
<
div
className=
"grid grid-cols-1 lg:grid-cols-3 gap-6"
>
{
/* Main content */
}
<
main
className=
"lg:col-span-2 bg-white border rounded-md p-6"
>
<
div
className=
'pb-5 text-primary text-2xl leading-normal font-medium'
>
{
isLoading
?
(
<
div
className=
"flex justify-center items-center py-12"
>
<
Spinner
className=
"size-8"
/>
<
span
className=
"ml-2 text-gray-600"
>
Đang tải chi tiết môi trường kinh doanh...
</
span
>
</
div
>
)
:
data
?.
responseData
?
(
<>
<
div
className=
'pb-5 text-primary text-2xl leading-normal font-medium'
>
{
data
?.
responseData
?.
title
}
</
div
>
<
hr
className=
"py-2"
/>
<
div
className=
"p-7.5 prose tiptap overflow-hidden"
>
{
parse
(
data
?.
responseData
?.
description
??
''
)
}
</
div
>
<
div
className=
"p-7.5 prose tiptap overflow-hidden"
>
{
parse
(
data
?.
responseData
?.
description
??
''
)
}
</
div
>
</>
)
:
(
<
p
className=
"text-center py-4"
>
Không có dữ liệu
</
p
>
)
}
</
main
>
{
/* Sidebar */
}
...
...
src/app/(main)/xuc-tien-thuong-mai/moi-truong-kinh-doanh/page.tsx
View file @
74a04b88
...
...
@@ -9,12 +9,13 @@ import EventCalendar from "@app/dai-dien-gioi-chu/components/event-calendar";
import
{
useGetNews
}
from
"@api/endpoints/news"
;
import
{
GetNewsResponseType
}
from
"@api/types/NewsPage.type"
;
import
{
PATHS
}
from
"@constants/paths"
;
import
{
Spinner
}
from
"@components/ui/spinner"
;
export
default
function
Page
()
{
const
[
submitSearch
]
=
useState
(
""
);
const
[
page
,
setPage
]
=
useState
(
1
);
const
pageSize
=
5
;
const
{
data
:
allData
}
=
useGetNews
<
GetNewsResponseType
>
({
const
{
data
:
allData
,
isLoading
}
=
useGetNews
<
GetNewsResponseType
>
({
pageSize
:
String
(
pageSize
),
currentPage
:
String
(
page
),
// filters: submitSearch ? `title @=${submitSearch}` : undefined,
...
...
@@ -29,30 +30,41 @@ export default function Page() {
{
/* Main content */
}
<
main
className=
"lg:col-span-2 bg-background "
>
<
div
className=
"pb-5 overflow-hidden"
>
{
allData
?.
responseData
.
rows
.
map
((
news
)
=>
(
<
NewsContent
key=
{
news
.
id
}
news=
{
news
}
link=
{
`${PATHS.tradePromotion}/${news.id}`
}
/>
))
}
{
isLoading
?
(
<
div
className=
"flex justify-center items-center py-12"
>
<
Spinner
className=
"size-8"
/>
<
span
className=
"ml-2 text-gray-600"
>
Đang tải môi trường kinh doanh...
</
span
>
</
div
>
)
:
allData
?.
responseData
.
rows
.
length
===
0
?
(
<
p
className=
"text-center py-4"
>
Không có dữ liệu
</
p
>
)
:
(
<>
{
allData
?.
responseData
.
rows
.
map
((
news
)
=>
(
<
NewsContent
key=
{
news
.
id
}
news=
{
news
}
link=
{
`${PATHS.tradePromotion}/${news.id}`
}
/>
))
}
<
div
className=
"w-full flex justify-center mt-4"
>
<
Pagination
pageCount=
{
Number
(
allData
?.
responseData
.
totalPages
??
1
)
}
page=
{
Number
(
allData
?.
responseData
.
currentPage
??
page
)
}
onChangePage=
{
(
p
)
=>
setPage
(
p
)
}
onGoToPreviousPage=
{
()
=>
setPage
(
Math
.
max
(
1
,
page
-
1
))
}
onGoToNextPage=
{
()
=>
setPage
(
Math
.
min
(
Number
(
allData
?.
responseData
.
totalPages
??
1
),
page
+
1
)
)
}
/>
</
div
>
<
div
className=
"w-full flex justify-center mt-4"
>
<
Pagination
pageCount=
{
Number
(
allData
?.
responseData
.
totalPages
??
1
)
}
page=
{
Number
(
allData
?.
responseData
.
currentPage
??
page
)
}
onChangePage=
{
(
p
)
=>
setPage
(
p
)
}
onGoToPreviousPage=
{
()
=>
setPage
(
Math
.
max
(
1
,
page
-
1
))
}
onGoToNextPage=
{
()
=>
setPage
(
Math
.
min
(
Number
(
allData
?.
responseData
.
totalPages
??
1
),
page
+
1
)
)
}
/>
</
div
>
</>
)
}
</
div
>
</
main
>
...
...
src/app/(main)/xuc-tien-thuong-mai/page.tsx
View file @
74a04b88
...
...
@@ -8,12 +8,13 @@ import Image from "next/image";
import
{
useGetNews
}
from
"@api/endpoints/news"
;
import
{
GetNewsResponseType
}
from
"@api/types/NewsPage.type"
;
import
{
PATHS
}
from
"@constants/paths"
;
import
{
Spinner
}
from
"@components/ui/spinner"
;
export
default
function
Page
()
{
const
[
submitSearch
]
=
useState
(
""
);
const
[
page
,
setPage
]
=
useState
(
1
);
const
pageSize
=
5
;
const
{
data
:
allData
}
=
useGetNews
<
GetNewsResponseType
>
({
const
{
data
:
allData
,
isLoading
}
=
useGetNews
<
GetNewsResponseType
>
({
pageSize
:
String
(
pageSize
),
currentPage
:
String
(
page
),
filters
:
submitSearch
?
`title @=
${
submitSearch
}
`
:
undefined
,
...
...
@@ -27,26 +28,35 @@ export default function Page() {
{
/* Main content */
}
<
main
className=
"lg:col-span-2 bg-background "
>
<
div
className=
"pb-5 overflow-hidden"
>
{
allData
?.
responseData
.
rows
.
map
((
news
)
=>
(
<
NewsContent
key=
{
news
.
id
}
news=
{
news
}
link=
{
`${PATHS.tradePromotion}/${news.id}`
}
/>
))
}
{
isLoading
?
(
<
div
className=
"flex justify-center items-center py-12"
>
<
Spinner
className=
"size-8"
/>
<
span
className=
"ml-2 text-gray-600"
>
Đang tải tin xúc tiến thương mại...
</
span
>
</
div
>
)
:
(
<>
{
allData
?.
responseData
.
rows
.
map
((
news
)
=>
(
<
NewsContent
key=
{
news
.
id
}
news=
{
news
}
link=
{
`${PATHS.tradePromotion}/${news.id}`
}
/>
))
}
<
div
className=
"w-full flex justify-center mt-4"
>
<
Pagination
pageCount=
{
Number
(
allData
?.
responseData
.
totalPages
??
1
)
}
page=
{
Number
(
allData
?.
responseData
.
currentPage
??
page
)
}
onChangePage=
{
(
p
)
=>
setPage
(
p
)
}
onGoToPreviousPage=
{
()
=>
setPage
(
Math
.
max
(
1
,
page
-
1
))
}
onGoToNextPage=
{
()
=>
setPage
(
Math
.
min
(
Number
(
allData
?.
responseData
.
totalPages
??
1
),
page
+
1
<
div
className=
"w-full flex justify-center mt-4"
>
<
Pagination
pageCount=
{
Number
(
allData
?.
responseData
.
totalPages
??
1
)
}
page=
{
Number
(
allData
?.
responseData
.
currentPage
??
page
)
}
onChangePage=
{
(
p
)
=>
setPage
(
p
)
}
onGoToPreviousPage=
{
()
=>
setPage
(
Math
.
max
(
1
,
page
-
1
))
}
onGoToNextPage=
{
()
=>
setPage
(
Math
.
min
(
Number
(
allData
?.
responseData
.
totalPages
??
1
),
page
+
1
)
)
}
/>
</
div
>
)
}
/>
</
div
>
</>
)
}
</
div
>
</
main
>
...
...
src/components/ui/loading-state.tsx
0 → 100644
View file @
74a04b88
import
{
Spinner
}
from
"@/components/ui/spinner"
;
import
{
cn
}
from
"@/lib/utils"
;
interface
LoadingStateProps
{
message
?:
string
;
size
?:
"sm"
|
"md"
|
"lg"
;
className
?:
string
;
showMessage
?:
boolean
;
}
export
function
LoadingState
({
message
=
"Đang tải dữ liệu..."
,
size
=
"md"
,
className
,
showMessage
=
true
}:
LoadingStateProps
)
{
const
sizeClasses
=
{
sm
:
"size-4"
,
md
:
"size-6"
,
lg
:
"size-8"
};
const
paddingClasses
=
{
sm
:
"py-6"
,
md
:
"py-8"
,
lg
:
"py-12"
};
return
(
<
div
className=
{
cn
(
"flex justify-center items-center"
,
paddingClasses
[
size
],
className
)
}
>
<
Spinner
className=
{
sizeClasses
[
size
]
}
/>
{
showMessage
&&
(
<
span
className=
"ml-2 text-gray-600"
>
{
message
}
</
span
>
)
}
</
div
>
);
}
// Các preset thường dùng
export
const
LoadingPresets
=
{
News
:
()
=>
<
LoadingState
message=
"Đang tải tin tức..."
/>,
Search
:
()
=>
<
LoadingState
message=
"Đang tìm kiếm..."
/>,
Content
:
()
=>
<
LoadingState
message=
"Đang tải nội dung..."
/>,
Data
:
()
=>
<
LoadingState
message=
"Đang tải dữ liệu..."
/>,
Members
:
()
=>
<
LoadingState
message=
"Đang tải thông tin hội viên..."
/>,
Events
:
()
=>
<
LoadingState
message=
"Đang tải sự kiện..."
/>,
Small
:
(
message
?:
string
)
=>
<
LoadingState
size=
"sm"
message=
{
message
}
/>,
Large
:
(
message
?:
string
)
=>
<
LoadingState
size=
"lg"
message=
{
message
}
/>,
};
\ No newline at end of file
src/lib/types/common.ts
0 → 100644
View file @
74a04b88
// Query response type
interface
ResponseType
<
T
=
any
>
{
data
:
any
message
:
string
|
null
message_en
:
string
|
null
responseData
:
T
status
:
'fail'
|
'success'
statusCode
:
number
timeStamp
:
string
violations
:
Array
<
{
code
:
number
message
:
string
action
:
Array
<
{
location
:
string
msg
:
{
en
:
string
vi
:
string
}
path
:
string
value
:
string
}
>
}
>
|
null
}
// Infinite query statuses type
interface
InfiniteQueryStatusesType
{
isFetchingInitialPage
:
boolean
isFetchingNextPage
:
boolean
isEmptyData
:
boolean
isError
?:
boolean
}
export
type
{
ResponseType
,
InfiniteQueryStatusesType
}
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