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
Show 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
=
{
export
type
EventStatus
=
{
id
:
string
;
id
:
string
;
name
:
string
;
name
:
string
;
...
@@ -22,7 +23,68 @@ export type EventOrganization = {
...
@@ -22,7 +23,68 @@ export type EventOrganization = {
add_info
:
unknown
|
null
;
add_info
:
unknown
|
null
;
organization
:
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
=
{
export
type
EventItem
=
{
id
:
string
;
id
:
string
;
name
:
string
;
name
:
string
;
...
...
src/app/(main)/_lib/layout/header.tsx
View file @
74a04b88
"use client"
;
"use client"
;
import
React
,
{
useState
}
from
"react"
;
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
{
Menu
,
X
,
Facebook
,
Linkedin
,
Twitter
,
Youtube
}
from
"lucide-react"
;
import
logo
from
"@/assets/VCCI-HCM-logo-VN-2025.png"
;
import
logo
from
"@/assets/VCCI-HCM-logo-VN-2025.png"
;
import
Image
from
"next/image"
;
import
Image
from
"next/image"
;
...
@@ -8,33 +8,33 @@ import MenuItem from "./MenuItem";
...
@@ -8,33 +8,33 @@ import MenuItem from "./MenuItem";
import
Link
from
"next/link"
;
import
Link
from
"next/link"
;
function
Header
()
{
function
Header
()
{
const
[
toggleMenu
,
setToggleMenu
]
=
useState
<
boolean
>
(
false
);
const
[
toggleMenu
,
setToggleMenu
]
=
useState
<
boolean
>
(
false
);
const
router
=
useRouter
()
const
router
=
useRouter
()
;
return
(
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=
"container w-full px-4 flex items-center justify-between"
>
<
div
className=
"flex items-center gap-3"
>
<
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]"
>
<
div
className=
"w-[130px] h-
9
bg-[#e8c518] flex items-center justify-center border-4 rounded-sm border-[#647792]"
>
<
a
<
Link
className=
"font-
[600] text-[14px] text-[#063E8E]
hover:text-white transition"
className=
"font-
semibold text-[14px] text-primary
hover:text-white transition"
href=
"
#
"
href=
"
https://vccihcm.vn/dang-ky
"
>
>
Đăng Ký Hội Viên
Đăng Ký Hội Viên
</
a
>
</
Link
>
</
div
>
</
div
>
<
a
<
Link
className=
"px-3 py-2 text-[14px] text-white hover:opacity-80"
className=
"px-3 py-2 text-[14px] text-white hover:opacity-80"
href=
"
#
"
href=
"
/site-map
"
>
>
Sitemap
Sitemap
</
a
>
</
Link
>
<
a
<
Link
className=
"px-3 py-2 text-[14px] text-white hover:opacity-80"
className=
"px-3 py-2 text-[14px] text-white hover:opacity-80"
href=
"
#
"
href=
"
https://vccihcm.vn/lien-he
"
>
>
Liên hệ
Liên hệ
</
a
>
</
Link
>
</
div
>
</
div
>
<
div
className=
"flex items-center gap-8"
>
<
div
className=
"flex items-center gap-8"
>
...
@@ -43,10 +43,11 @@ function Header() {
...
@@ -43,10 +43,11 @@ function Header() {
type=
"text"
type=
"text"
placeholder=
"Tìm kiếm"
placeholder=
"Tìm kiếm"
onKeyDown=
{
(
e
)
=>
{
onKeyDown=
{
(
e
)
=>
{
if
(
e
.
key
===
'Enter'
)
{
if
(
e
.
key
===
"Enter"
)
{
const
value
=
(
e
.
currentTarget
as
HTMLInputElement
).
value
||
''
const
value
=
const
encoded
=
encodeURIComponent
(
value
)
(
e
.
currentTarget
as
HTMLInputElement
).
value
||
""
;
router
.
push
(
`/search?q=${encoded}`
)
const
encoded
=
encodeURIComponent
(
value
);
router
.
push
(
`/search?q=${encoded}`
);
}
}
}
}
}
}
/>
/>
...
@@ -92,7 +93,6 @@ function Header() {
...
@@ -92,7 +93,6 @@ function Header() {
{
title
:
"Sơ Đồ Tổ Chức"
,
link
:
"so-do-to-chuc"
},
{
title
:
"Sơ Đồ Tổ Chức"
,
link
:
"so-do-to-chuc"
},
{
title
:
"Dịch Vụ Cung Cấp"
,
link
:
"dich-vu-cung-cap"
},
{
title
:
"Dịch Vụ Cung Cấp"
,
link
:
"dich-vu-cung-cap"
},
]
}
]
}
/>
/>
<
MenuItem
<
MenuItem
title=
"Hội viên"
title=
"Hội viên"
...
@@ -106,7 +106,6 @@ function Header() {
...
@@ -106,7 +106,6 @@ function Header() {
{
title
:
"Kết Nối Hội Viên"
,
link
:
"ket-noi-hoi-vien"
},
{
title
:
"Kết Nối Hội Viên"
,
link
:
"ket-noi-hoi-vien"
},
{
title
:
"Tin Hội Viên"
,
link
:
"tin-hoi-vien"
},
{
title
:
"Tin Hội Viên"
,
link
:
"tin-hoi-vien"
},
]
}
]
}
/>
/>
<
MenuItem
<
MenuItem
title=
"Hoạt động"
title=
"Hoạt động"
...
@@ -207,7 +206,6 @@ function Header() {
...
@@ -207,7 +206,6 @@ function Header() {
{
title
:
"Cơ Hội Kinh Doanh"
,
link
:
"co-hoi-kinh-doanh"
},
{
title
:
"Cơ Hội Kinh Doanh"
,
link
:
"co-hoi-kinh-doanh"
},
{
title
:
"Hỗ Trợ Kinh Doanh"
,
link
:
"ho-tro-kinh-doanh"
},
{
title
:
"Hỗ Trợ Kinh Doanh"
,
link
:
"ho-tro-kinh-doanh"
},
]
}
]
}
/>
/>
<
MenuItem
<
MenuItem
title=
"Thông tin truyền thông"
title=
"Thông tin truyền thông"
...
@@ -224,7 +222,6 @@ function Header() {
...
@@ -224,7 +222,6 @@ function Header() {
{
title
:
"Ấn Phẩm"
,
link
:
"an-pham"
},
{
title
:
"Ấn Phẩm"
,
link
:
"an-pham"
},
{
title
:
"Thư Viện Tài Liệu"
,
link
:
"thu-vien-tai-lieu"
},
{
title
:
"Thư Viện Tài Liệu"
,
link
:
"thu-vien-tai-lieu"
},
]
}
]
}
/>
/>
</
nav
>
</
nav
>
...
@@ -240,7 +237,8 @@ function Header() {
...
@@ -240,7 +237,8 @@ function Header() {
{
/* Mobile Menu */
}
{
/* Mobile Menu */
}
<
div
<
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"
}`
}
}`
}
>
>
{
[
{
[
...
...
src/app/(main)/dai-dien-gioi-chu/chu-de/page.tsx
View file @
74a04b88
...
@@ -9,12 +9,13 @@ import Image from "next/image";
...
@@ -9,12 +9,13 @@ import Image from "next/image";
import
{
useGetNews
}
from
"@api/endpoints/news"
;
import
{
useGetNews
}
from
"@api/endpoints/news"
;
import
{
GetNewsResponseType
}
from
"@api/types/NewsPage.type"
;
import
{
GetNewsResponseType
}
from
"@api/types/NewsPage.type"
;
import
{
PATHS
}
from
"@constants/paths"
;
import
{
PATHS
}
from
"@constants/paths"
;
import
{
Spinner
}
from
"@components/ui/spinner"
;
export
default
function
Page
()
{
export
default
function
Page
()
{
const
[
submitSearch
]
=
useState
(
""
);
const
[
submitSearch
]
=
useState
(
""
);
const
[
page
,
setPage
]
=
useState
(
1
);
const
[
page
,
setPage
]
=
useState
(
1
);
const
pageSize
=
5
;
const
pageSize
=
5
;
const
{
data
:
allData
}
=
useGetNews
<
GetNewsResponseType
>
({
const
{
data
:
allData
,
isLoading
}
=
useGetNews
<
GetNewsResponseType
>
({
pageSize
:
String
(
pageSize
),
pageSize
:
String
(
pageSize
),
currentPage
:
String
(
page
),
currentPage
:
String
(
page
),
// filters: submitSearch ? `title @=${submitSearch}` : undefined,
// filters: submitSearch ? `title @=${submitSearch}` : undefined,
...
@@ -29,6 +30,13 @@ export default function Page() {
...
@@ -29,6 +30,13 @@ export default function Page() {
{
/* Main content */
}
{
/* Main content */
}
<
main
className=
"lg:col-span-2 bg-background "
>
<
main
className=
"lg:col-span-2 bg-background "
>
<
div
className=
"pb-5 overflow-hidden"
>
<
div
className=
"pb-5 overflow-hidden"
>
{
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
)
=>
(
{
allData
?.
responseData
.
rows
.
map
((
news
)
=>
(
<
NewsContent
key=
{
news
.
id
}
news=
{
news
}
link=
{
`${PATHS.ownerRepresentatives}/chu-de/${news.id}`
}
/>
<
NewsContent
key=
{
news
.
id
}
news=
{
news
}
link=
{
`${PATHS.ownerRepresentatives}/chu-de/${news.id}`
}
/>
))
}
))
}
...
@@ -49,6 +57,8 @@ export default function Page() {
...
@@ -49,6 +57,8 @@ export default function Page() {
}
}
/>
/>
</
div
>
</
div
>
</>
)
}
</
div
>
</
div
>
</
main
>
</
main
>
...
...
src/app/(main)/dai-dien-gioi-chu/components/card-news/index.tsx
View file @
74a04b88
...
@@ -2,7 +2,7 @@
...
@@ -2,7 +2,7 @@
import
{
NewsItem
}
from
'@app/dai-dien-gioi-chu/lib/types/NewsPage.type'
;
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
{
EventItem
}
from
"@api/types/event"
;
// Helper: remove <img> tags and extract plain text from HTML
// Helper: remove <img> tags and extract plain text from HTML
const
stripImagesAndHtml
=
(
html
?:
string
)
=>
{
const
stripImagesAndHtml
=
(
html
?:
string
)
=>
{
if
(
!
html
)
return
''
if
(
!
html
)
return
''
...
@@ -19,7 +19,7 @@ const stripImagesAndHtml = (html?: string) => {
...
@@ -19,7 +19,7 @@ const stripImagesAndHtml = (html?: string) => {
}
}
return
withoutImgs
.
replace
(
/<
[^
>
]
*>/g
,
''
)
return
withoutImgs
.
replace
(
/<
[^
>
]
*>/g
,
''
)
}
}
function
NewsContent
({
news
,
link
}:
{
news
:
NewsItem
,
link
:
string
})
{
function
NewsContent
({
news
,
link
,
event
}:
{
news
?:
NewsItem
,
link
:
string
,
event
?:
EventItem
})
{
return
(
return
(
<
a
<
a
...
@@ -27,8 +27,8 @@ function NewsContent({ news ,link}: { news: NewsItem ,link:string}) {
...
@@ -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"
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
<
img
src=
{
`${Links.imageEndpoint}${news
.thumbnail
}`
}
src=
{
`${Links.imageEndpoint}${news
?news.thumbnail:event?.image
}`
}
alt=
{
news
.
titl
e
}
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"
className=
"w-full sm:w-56 md:w-64 h-40 md:h-36 object-cover shrink-0"
onError=
{
(
e
)
=>
{
onError=
{
(
e
)
=>
{
e
.
currentTarget
.
src
=
"/img-error.png"
e
.
currentTarget
.
src
=
"/img-error.png"
...
@@ -38,13 +38,13 @@ function NewsContent({ news ,link}: { news: NewsItem ,link:string}) {
...
@@ -38,13 +38,13 @@ function NewsContent({ news ,link}: { news: NewsItem ,link:string}) {
<
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"
>
<
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
>
</
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 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
>
</
div
>
</
div
>
</
a
>
</
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";
...
@@ -9,12 +9,13 @@ import Image from "next/image";
import
{
useGetNews
}
from
"@api/endpoints/news"
;
import
{
useGetNews
}
from
"@api/endpoints/news"
;
import
{
GetNewsResponseType
}
from
"@api/types/NewsPage.type"
;
import
{
GetNewsResponseType
}
from
"@api/types/NewsPage.type"
;
import
{
PATHS
}
from
"@constants/paths"
;
import
{
PATHS
}
from
"@constants/paths"
;
import
{
Spinner
}
from
"@components/ui/spinner"
;
export
default
function
Page
()
{
export
default
function
Page
()
{
const
[
submitSearch
]
=
useState
(
""
);
const
[
submitSearch
]
=
useState
(
""
);
const
[
page
,
setPage
]
=
useState
(
1
);
const
[
page
,
setPage
]
=
useState
(
1
);
const
pageSize
=
5
;
const
pageSize
=
5
;
const
{
data
:
allData
}
=
useGetNews
<
GetNewsResponseType
>
({
const
{
data
:
allData
,
isLoading
}
=
useGetNews
<
GetNewsResponseType
>
({
pageSize
:
String
(
pageSize
),
pageSize
:
String
(
pageSize
),
currentPage
:
String
(
page
),
currentPage
:
String
(
page
),
filters
:
submitSearch
?
`title @=
${
submitSearch
}
`
:
undefined
,
filters
:
submitSearch
?
`title @=
${
submitSearch
}
`
:
undefined
,
...
@@ -28,6 +29,13 @@ export default function Page() {
...
@@ -28,6 +29,13 @@ export default function Page() {
{
/* Main content */
}
{
/* Main content */
}
<
main
className=
"lg:col-span-2 bg-background "
>
<
main
className=
"lg:col-span-2 bg-background "
>
<
div
className=
"pb-5 overflow-hidden"
>
<
div
className=
"pb-5 overflow-hidden"
>
{
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
)
=>
(
{
allData
?.
responseData
.
rows
.
map
((
news
)
=>
(
<
NewsContent
key=
{
news
.
id
}
news=
{
news
}
link=
{
`${PATHS.ownerRepresentatives}/tap-huan-nsdld/${news.id}`
}
/>
<
NewsContent
key=
{
news
.
id
}
news=
{
news
}
link=
{
`${PATHS.ownerRepresentatives}/tap-huan-nsdld/${news.id}`
}
/>
))
}
))
}
...
@@ -48,6 +56,8 @@ export default function Page() {
...
@@ -48,6 +56,8 @@ export default function Page() {
}
}
/>
/>
</
div
>
</
div
>
</>
)
}
</
div
>
</
div
>
</
main
>
</
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";
...
@@ -9,12 +9,13 @@ import Image from "next/image";
import
{
useGetNews
}
from
"@api/endpoints/news"
;
import
{
useGetNews
}
from
"@api/endpoints/news"
;
import
{
GetNewsResponseType
}
from
"@api/types/NewsPage.type"
;
import
{
GetNewsResponseType
}
from
"@api/types/NewsPage.type"
;
import
{
PATHS
}
from
"@constants/paths"
;
import
{
PATHS
}
from
"@constants/paths"
;
import
{
Spinner
}
from
"@components/ui/spinner"
;
export
default
function
Page
()
{
export
default
function
Page
()
{
const
[
submitSearch
,
setsubmitSearch
]
=
useState
(
""
);
const
[
submitSearch
,
setsubmitSearch
]
=
useState
(
""
);
const
[
page
,
setPage
]
=
useState
(
1
);
const
[
page
,
setPage
]
=
useState
(
1
);
const
pageSize
=
5
;
const
pageSize
=
5
;
const
{
data
:
allData
}
=
useGetNews
<
GetNewsResponseType
>
({
const
{
data
:
allData
,
isLoading
}
=
useGetNews
<
GetNewsResponseType
>
({
pageSize
:
String
(
pageSize
),
pageSize
:
String
(
pageSize
),
currentPage
:
String
(
page
),
currentPage
:
String
(
page
),
filters
:
submitSearch
?
`title @=
${
submitSearch
}
,category@=Tin liên quan`
:
'category@=Tin liên quan'
,
filters
:
submitSearch
?
`title @=
${
submitSearch
}
,category@=Tin liên quan`
:
'category@=Tin liên quan'
,
...
@@ -28,6 +29,13 @@ export default function Page() {
...
@@ -28,6 +29,13 @@ export default function Page() {
{
/* Main content */
}
{
/* Main content */
}
<
main
className=
"lg:col-span-2 bg-background "
>
<
main
className=
"lg:col-span-2 bg-background "
>
<
div
className=
"pb-5 overflow-hidden"
>
<
div
className=
"pb-5 overflow-hidden"
>
{
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
)
=>
(
{
allData
?.
responseData
.
rows
.
map
((
news
)
=>
(
<
NewsContent
key=
{
news
.
id
}
news=
{
news
}
link=
{
`${PATHS.ownerRepresentatives}/tin-lien-quan/${news.id}`
}
/>
<
NewsContent
key=
{
news
.
id
}
news=
{
news
}
link=
{
`${PATHS.ownerRepresentatives}/tin-lien-quan/${news.id}`
}
/>
))
}
))
}
...
@@ -41,6 +49,8 @@ export default function Page() {
...
@@ -41,6 +49,8 @@ export default function Page() {
onGoToNextPage=
{
()
=>
setPage
(
Math
.
min
(
Number
(
allData
?.
responseData
.
totalPages
??
1
),
page
+
1
))
}
onGoToNextPage=
{
()
=>
setPage
(
Math
.
min
(
Number
(
allData
?.
responseData
.
totalPages
??
1
),
page
+
1
))
}
/>
/>
</
div
>
</
div
>
</>
)
}
</
div
>
</
div
>
</
main
>
</
main
>
...
...
src/app/(main)/hoat-dong/dao-tao/page.tsx
View file @
74a04b88
...
@@ -9,12 +9,13 @@ import Image from "next/image";
...
@@ -9,12 +9,13 @@ import Image from "next/image";
import
{
useGetNews
}
from
"@api/endpoints/news"
;
import
{
useGetNews
}
from
"@api/endpoints/news"
;
import
{
GetNewsResponseType
}
from
"@api/types/NewsPage.type"
;
import
{
GetNewsResponseType
}
from
"@api/types/NewsPage.type"
;
import
{
PATHS
}
from
"@constants/paths"
;
import
{
PATHS
}
from
"@constants/paths"
;
import
{
Spinner
}
from
"@components/ui/spinner"
;
export
default
function
Page
()
{
export
default
function
Page
()
{
const
[
submitSearch
]
=
useState
(
""
);
const
[
submitSearch
]
=
useState
(
""
);
const
[
page
,
setPage
]
=
useState
(
1
);
const
[
page
,
setPage
]
=
useState
(
1
);
const
pageSize
=
5
;
const
pageSize
=
5
;
const
{
data
:
allData
}
=
useGetNews
<
GetNewsResponseType
>
({
const
{
data
:
allData
,
isLoading
}
=
useGetNews
<
GetNewsResponseType
>
({
pageSize
:
String
(
pageSize
),
pageSize
:
String
(
pageSize
),
currentPage
:
String
(
page
),
currentPage
:
String
(
page
),
filters
:
submitSearch
?
`title @=
${
submitSearch
}
`
:
'category @=Đào tạo'
,
filters
:
submitSearch
?
`title @=
${
submitSearch
}
`
:
'category @=Đào tạo'
,
...
@@ -28,6 +29,13 @@ export default function Page() {
...
@@ -28,6 +29,13 @@ export default function Page() {
{
/* Main content */
}
{
/* Main content */
}
<
main
className=
"lg:col-span-2 bg-background "
>
<
main
className=
"lg:col-span-2 bg-background "
>
<
div
className=
"pb-5 overflow-hidden"
>
<
div
className=
"pb-5 overflow-hidden"
>
{
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
)
=>
(
{
allData
?.
responseData
.
rows
.
map
((
news
)
=>
(
<
NewsContent
key=
{
news
.
id
}
news=
{
news
}
link=
{
`${PATHS.event}/dao-tao/${news.id}`
}
/>
<
NewsContent
key=
{
news
.
id
}
news=
{
news
}
link=
{
`${PATHS.event}/dao-tao/${news.id}`
}
/>
))
}
))
}
...
@@ -41,6 +49,8 @@ export default function Page() {
...
@@ -41,6 +49,8 @@ export default function Page() {
onGoToNextPage=
{
()
=>
setPage
(
Math
.
min
(
Number
(
allData
?.
responseData
.
totalPages
??
1
),
page
+
1
))
}
onGoToNextPage=
{
()
=>
setPage
(
Math
.
min
(
Number
(
allData
?.
responseData
.
totalPages
??
1
),
page
+
1
))
}
/>
/>
</
div
>
</
div
>
</>
)
}
</
div
>
</
div
>
</
main
>
</
main
>
...
...
src/app/(main)/hoat-dong/su-kien/[id]/page.tsx
View file @
74a04b88
...
@@ -4,14 +4,16 @@ import Image from "next/image";
...
@@ -4,14 +4,16 @@ import Image from "next/image";
import
ListCategory
from
"@app/dai-dien-gioi-chu/components/list-category"
;
import
ListCategory
from
"@app/dai-dien-gioi-chu/components/list-category"
;
import
{
EVENT_CATEGORIES
}
from
"@constants/categories"
;
import
{
EVENT_CATEGORIES
}
from
"@constants/categories"
;
import
ListFilter
from
"@app/dai-dien-gioi-chu/components/list-filter"
;
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
parse
from
"html-react-parser"
;
import
{
useParams
}
from
'next/navigation'
import
{
useParams
}
from
'next/navigation'
import
{
GetNewsDetailResponseType
}
from
'@lib/types/news-detail-response-data'
;
import
{
GetNewsDetailResponseType
}
from
'@lib/types/news-detail-response-data'
;
import
{
GetEventsIdQueryResponseType
}
from
'@api/types/event'
;
import
{
Spinner
}
from
"@components/ui/spinner"
;
// ...existing code...
// ...existing code...
const
Page
:
React
.
FC
=
()
=>
{
const
Page
:
React
.
FC
=
()
=>
{
const
{
id
}
=
useParams
()
const
{
id
}
=
useParams
()
const
{
data
,
isLoading
}
=
useGet
NewsId
<
GetNewsDetail
ResponseType
>
(
id
as
string
)
const
{
data
,
isLoading
}
=
useGet
EventsId
<
GetEventsIdQuery
ResponseType
>
(
id
as
string
)
return
(
return
(
<
div
className=
"min-h-screen w-full container mx-auto p-4"
>
<
div
className=
"min-h-screen w-full container mx-auto p-4"
>
<
div
className=
"w-full flex flex-col gap-5"
>
<
div
className=
"w-full flex flex-col gap-5"
>
...
@@ -20,11 +22,20 @@ const Page: React.FC = () => {
...
@@ -20,11 +22,20 @@ const Page: React.FC = () => {
<
div
className=
"grid grid-cols-1 lg:grid-cols-3 gap-6"
>
<
div
className=
"grid grid-cols-1 lg:grid-cols-3 gap-6"
>
{
/* Main content */
}
{
/* Main content */
}
<
main
className=
"lg:col-span-2 bg-white border rounded-md p-6"
>
<
main
className=
"lg:col-span-2 bg-white border rounded-md p-6"
>
{
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'
>
<
div
className=
'pb-5 text-primary text-2xl leading-normal font-medium'
>
{
data
?.
responseData
?.
titl
e
}
{
data
?.
responseData
?.
nam
e
}
</
div
>
</
div
>
<
hr
className=
"py-2"
/>
<
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
>
</
main
>
{
/* Sidebar */
}
{
/* 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";
...
@@ -7,18 +7,23 @@ import NewsContent from "@app/dai-dien-gioi-chu/components/card-news";
// ...existing code...
// ...existing code...
import
{
Pagination
}
from
"@components/base/pagination"
;
import
{
Pagination
}
from
"@components/base/pagination"
;
import
Image
from
"next/image"
;
import
Image
from
"next/image"
;
import
{
useGetEvents
}
from
'@api/endpoints/event'
import
{
EventApiResponse
}
from
'@api/types/event'
import
{
useGetNews
}
from
"@api/endpoints/news"
;
import
{
useGetNews
}
from
"@api/endpoints/news"
;
import
{
GetNewsResponseType
}
from
"@api/types/NewsPage.type"
;
import
{
GetNewsResponseType
}
from
"@api/types/NewsPage.type"
;
import
{
PATHS
}
from
"@constants/paths"
;
import
{
PATHS
}
from
"@constants/paths"
;
import
{
Spinner
}
from
"@components/ui/spinner"
;
export
default
function
Page
()
{
export
default
function
Page
()
{
const
[
submitSearch
]
=
useState
(
""
);
const
[
submitSearch
]
=
useState
(
""
);
const
[
page
,
setPage
]
=
useState
(
1
);
const
[
page
,
setPage
]
=
useState
(
1
);
const
pageSize
=
5
;
const
pageSize
=
5
;
const
{
data
:
allData
}
=
useGetNews
<
GetNewsResponseTyp
e
>
({
const
{
data
:
allData
,
isLoading
}
=
useGetEvents
<
EventApiRespons
e
>
({
pageSize
:
String
(
pageSize
),
pageSize
:
String
(
pageSize
),
currentPage
:
String
(
page
),
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
(
return
(
<
div
className=
"min-h-screen container mx-auto p-4"
>
<
div
className=
"min-h-screen container mx-auto p-4"
>
...
@@ -29,8 +34,15 @@ export default function Page() {
...
@@ -29,8 +34,15 @@ export default function Page() {
{
/* Main content */
}
{
/* Main content */
}
<
main
className=
"lg:col-span-2 bg-background "
>
<
main
className=
"lg:col-span-2 bg-background "
>
<
div
className=
"pb-5 overflow-hidden"
>
<
div
className=
"pb-5 overflow-hidden"
>
{
allData
?.
responseData
.
rows
.
map
((
news
)
=>
(
{
isLoading
?
(
<
NewsContent
key=
{
news
.
id
}
news=
{
news
}
link=
{
`${PATHS.event}/su-kien/${news.id}`
}
/>
<
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"
>
<
div
className=
"w-full flex justify-center mt-4"
>
...
@@ -42,6 +54,8 @@ export default function Page() {
...
@@ -42,6 +54,8 @@ export default function Page() {
onGoToNextPage=
{
()
=>
setPage
(
Math
.
min
(
Number
(
allData
?.
responseData
.
totalPages
??
1
),
page
+
1
))
}
onGoToNextPage=
{
()
=>
setPage
(
Math
.
min
(
Number
(
allData
?.
responseData
.
totalPages
??
1
),
page
+
1
))
}
/>
/>
</
div
>
</
div
>
</>
)
}
</
div
>
</
div
>
</
main
>
</
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";
...
@@ -7,6 +7,7 @@ import { Pagination } from "@components/base/pagination";
import
Image
from
"next/image"
;
import
Image
from
"next/image"
;
import
{
useGetNews
}
from
"@api/endpoints/news"
;
import
{
useGetNews
}
from
"@api/endpoints/news"
;
import
{
GetNewsResponseType
}
from
"@api/types/NewsPage.type"
;
import
{
GetNewsResponseType
}
from
"@api/types/NewsPage.type"
;
import
{
Spinner
}
from
"@components/ui/spinner"
;
export
default
function
Page
()
{
export
default
function
Page
()
{
const
[
submitSearch
]
=
useState
(
""
);
const
[
submitSearch
]
=
useState
(
""
);
...
@@ -26,6 +27,13 @@ export default function Page() {
...
@@ -26,6 +27,13 @@ export default function Page() {
{
/* Main content */
}
{
/* Main content */
}
<
main
className=
"lg:col-span-2 bg-background"
>
<
main
className=
"lg:col-span-2 bg-background"
>
<
div
className=
"pb-5 overflow-hidden"
>
<
div
className=
"pb-5 overflow-hidden"
>
{
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
)
=>
(
{
allData
?.
responseData
.
rows
.
map
((
news
)
=>
(
<
CardNews
key=
{
news
.
id
}
news=
{
news
}
/>
<
CardNews
key=
{
news
.
id
}
news=
{
news
}
/>
))
}
))
}
...
@@ -46,6 +54,8 @@ export default function Page() {
...
@@ -46,6 +54,8 @@ export default function Page() {
}
}
/>
/>
</
div
>
</
div
>
</>
)
}
</
div
>
</
div
>
</
main
>
</
main
>
...
...
src/app/(main)/hoi-vien/tin-hoi-vien/page.tsx
View file @
74a04b88
...
@@ -7,6 +7,7 @@ import { Pagination } from '@components/base/pagination'
...
@@ -7,6 +7,7 @@ import { Pagination } from '@components/base/pagination'
import
Image
from
"next/image"
;
import
Image
from
"next/image"
;
import
{
useGetNews
}
from
'@api/endpoints/news'
import
{
useGetNews
}
from
'@api/endpoints/news'
import
{
GetNewsResponseType
}
from
'@api/types/NewsPage.type'
import
{
GetNewsResponseType
}
from
'@api/types/NewsPage.type'
import
{
Spinner
}
from
"@components/ui/spinner"
;
export
default
function
Page
()
{
export
default
function
Page
()
{
const
[
submitSearch
]
=
useState
(
''
)
const
[
submitSearch
]
=
useState
(
''
)
...
@@ -26,6 +27,13 @@ export default function Page() {
...
@@ -26,6 +27,13 @@ export default function Page() {
{
/* Main content */
}
{
/* Main content */
}
<
main
className=
"lg:col-span-2 bg-background"
>
<
main
className=
"lg:col-span-2 bg-background"
>
<
div
className=
'pb-5 overflow-hidden'
>
<
div
className=
'pb-5 overflow-hidden'
>
{
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
)
=>
(
{
allData
?.
responseData
.
rows
.
map
((
news
)
=>
(
<
CardNews
key=
{
news
.
id
}
news=
{
news
}
/>
<
CardNews
key=
{
news
.
id
}
news=
{
news
}
/>
))
}
))
}
...
@@ -46,6 +54,8 @@ export default function Page() {
...
@@ -46,6 +54,8 @@ export default function Page() {
}
}
/>
/>
</
div
>
</
div
>
</>
)
}
</
div
>
</
div
>
</
main
>
</
main
>
...
...
src/app/(main)/search/page.tsx
View file @
74a04b88
...
@@ -8,6 +8,7 @@ import { Pagination } from "@components/base/pagination";
...
@@ -8,6 +8,7 @@ import { Pagination } from "@components/base/pagination";
import
Image
from
"next/image"
;
import
Image
from
"next/image"
;
import
{
useGetNews
}
from
"@api/endpoints/news"
;
import
{
useGetNews
}
from
"@api/endpoints/news"
;
import
{
GetNewsResponseType
}
from
"@api/types/NewsPage.type"
;
import
{
GetNewsResponseType
}
from
"@api/types/NewsPage.type"
;
import
{
Spinner
}
from
"@components/ui/spinner"
;
import
{
PATHS
}
from
"@constants/paths"
;
import
{
PATHS
}
from
"@constants/paths"
;
import
{
useSearchParams
}
from
'next/navigation'
import
{
useSearchParams
}
from
'next/navigation'
...
@@ -16,7 +17,7 @@ function SearchContent() {
...
@@ -16,7 +17,7 @@ function SearchContent() {
const
searchParams
=
useSearchParams
()
const
searchParams
=
useSearchParams
()
const
query
=
searchParams
.
get
(
'q'
)
//
const
query
=
searchParams
.
get
(
'q'
)
//
const
pageSize
=
5
;
const
pageSize
=
5
;
const
{
data
:
allData
}
=
useGetNews
<
GetNewsResponseType
>
({
const
{
data
:
allData
,
isLoading
}
=
useGetNews
<
GetNewsResponseType
>
({
pageSize
:
String
(
pageSize
),
pageSize
:
String
(
pageSize
),
currentPage
:
String
(
page
),
currentPage
:
String
(
page
),
filters
:
query
?
`title @=
${
query
}
`
:
undefined
,
filters
:
query
?
`title @=
${
query
}
`
:
undefined
,
...
@@ -40,6 +41,13 @@ function SearchContent() {
...
@@ -40,6 +41,13 @@ function SearchContent() {
{
/* Main content */
}
{
/* Main content */
}
<
main
className=
"lg:col-span-2 bg-background "
>
<
main
className=
"lg:col-span-2 bg-background "
>
<
div
className=
"pb-5 overflow-hidden"
>
<
div
className=
"pb-5 overflow-hidden"
>
{
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
)
=>
(
{
allData
?.
responseData
.
rows
.
map
((
news
)
=>
(
<
NewsContent
<
NewsContent
key=
{
news
.
id
}
key=
{
news
.
id
}
...
@@ -64,6 +72,8 @@ function SearchContent() {
...
@@ -64,6 +72,8 @@ function SearchContent() {
}
}
/>
/>
</
div
>
</
div
>
</>
)
}
</
div
>
</
div
>
</
main
>
</
main
>
...
...
src/app/(main)/thong-tin-truyen-thong/chuyen-de/page.tsx
View file @
74a04b88
...
@@ -10,14 +10,15 @@ import Image from "next/image";
...
@@ -10,14 +10,15 @@ import Image from "next/image";
import
{
useGetNews
}
from
"@api/endpoints/news"
;
import
{
useGetNews
}
from
"@api/endpoints/news"
;
import
{
GetNewsResponseType
}
from
"@api/types/NewsPage.type"
;
import
{
GetNewsResponseType
}
from
"@api/types/NewsPage.type"
;
import
{
PATHS
}
from
"@constants/paths"
;
import
{
PATHS
}
from
"@constants/paths"
;
import
{
Spinner
}
from
"@components/ui/spinner"
;
export
default
function
Page
()
{
export
default
function
Page
()
{
const
[
submitSearch
]
=
useState
(
""
);
const
[
submitSearch
]
=
useState
(
""
);
const
[
page
,
setPage
]
=
useState
(
1
);
const
[
page
,
setPage
]
=
useState
(
1
);
const
pageSize
=
5
;
const
pageSize
=
5
;
const
{
data
:
allData
}
=
useGetNews
<
GetNewsResponseType
>
({
const
{
data
:
allData
,
isLoading
}
=
useGetNews
<
GetNewsResponseType
>
({
pageSize
:
String
(
pageSize
),
pageSize
:
String
(
pageSize
),
currentPage
:
String
(
page
),
currentPage
:
String
(
page
),
filters
:
submitSearch
?
`title @=
${
submitSearch
}
`
:
'category @=Chuyên đề'
,
filters
:
submitSearch
?
`title @=
${
submitSearch
}
,category @=Chuyên đề
`
:
'category @=Chuyên đề'
,
});
});
return
(
return
(
<
div
className=
"min-h-screen container mx-auto p-4"
>
<
div
className=
"min-h-screen container mx-auto p-4"
>
...
@@ -28,16 +29,22 @@ export default function Page() {
...
@@ -28,16 +29,22 @@ export default function Page() {
{
/* Main content */
}
{
/* Main content */
}
<
main
className=
"lg:col-span-2 bg-background "
>
<
main
className=
"lg:col-span-2 bg-background "
>
<
div
className=
"pb-5 overflow-hidden"
>
<
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
>
<
p
className=
"text-center py-4"
>
Không có dữ liệu
</
p
>
)
:
(
)
:
(
allData
?.
responseData
.
rows
.
map
((
news
)
=>
(
<>
{
allData
?.
responseData
.
rows
.
map
((
news
)
=>
(
<
NewsContent
<
NewsContent
key=
{
news
.
id
}
key=
{
news
.
id
}
news=
{
news
}
news=
{
news
}
link=
{
`${PATHS.mediaInformation}/chuyen-de/${news.id}`
}
link=
{
`${PATHS.mediaInformation}/chuyen-de/${news.id}`
}
/>
/>
)
))
}
))
}
<
div
className=
"w-full flex justify-center mt-4"
>
<
div
className=
"w-full flex justify-center mt-4"
>
<
Pagination
<
Pagination
...
@@ -48,6 +55,8 @@ export default function Page() {
...
@@ -48,6 +55,8 @@ export default function Page() {
onGoToNextPage=
{
()
=>
setPage
(
Math
.
min
(
Number
(
allData
?.
responseData
.
totalPages
??
1
),
page
+
1
))
}
onGoToNextPage=
{
()
=>
setPage
(
Math
.
min
(
Number
(
allData
?.
responseData
.
totalPages
??
1
),
page
+
1
))
}
/>
/>
</
div
>
</
div
>
</>
)
}
</
div
>
</
div
>
</
main
>
</
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() {
...
@@ -15,10 +15,10 @@ export default function Page() {
const
[
page
,
setPage
]
=
useState
(
1
);
const
[
page
,
setPage
]
=
useState
(
1
);
const
pageSize
=
5
;
const
pageSize
=
5
;
const
{
data
:
allData
}
=
useGetNews
<
GetNewsResponseType
>
({
const
{
data
:
allData
,
isLoading
}
=
useGetNews
<
GetNewsResponseType
>
({
pageSize
:
String
(
pageSize
),
pageSize
:
String
(
pageSize
),
currentPage
:
String
(
page
),
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
(
return
(
<
div
className=
"min-h-screen container mx-auto p-4"
>
<
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";
...
@@ -10,15 +10,16 @@ import Image from "next/image";
import
{
useGetNews
}
from
"@api/endpoints/news"
;
import
{
useGetNews
}
from
"@api/endpoints/news"
;
import
{
GetNewsResponseType
}
from
"@api/types/NewsPage.type"
;
import
{
GetNewsResponseType
}
from
"@api/types/NewsPage.type"
;
import
{
PATHS
}
from
"@constants/paths"
;
import
{
PATHS
}
from
"@constants/paths"
;
import
{
Spinner
}
from
"@components/ui/spinner"
;
export
default
function
Page
()
{
export
default
function
Page
()
{
const
[
submitSearch
]
=
useState
(
""
);
const
[
submitSearch
]
=
useState
(
""
);
const
[
page
,
setPage
]
=
useState
(
1
);
const
[
page
,
setPage
]
=
useState
(
1
);
const
pageSize
=
5
;
const
pageSize
=
5
;
const
{
data
:
allData
}
=
useGetNews
<
GetNewsResponseType
>
({
const
{
data
:
allData
,
isLoading
}
=
useGetNews
<
GetNewsResponseType
>
({
pageSize
:
String
(
pageSize
),
pageSize
:
String
(
pageSize
),
currentPage
:
String
(
page
),
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
(
return
(
<
div
className=
"min-h-screen container mx-auto p-4"
>
<
div
className=
"min-h-screen container mx-auto p-4"
>
...
@@ -29,16 +30,22 @@ export default function Page() {
...
@@ -29,16 +30,22 @@ export default function Page() {
{
/* Main content */
}
{
/* Main content */
}
<
main
className=
"lg:col-span-2 bg-background "
>
<
main
className=
"lg:col-span-2 bg-background "
>
<
div
className=
"pb-5 overflow-hidden"
>
<
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
>
<
p
className=
"text-center py-4"
>
Không có dữ liệu
</
p
>
)
:
(
)
:
(
allData
?.
responseData
.
rows
.
map
((
news
)
=>
(
<>
{
allData
?.
responseData
.
rows
.
map
((
news
)
=>
(
<
NewsContent
<
NewsContent
key=
{
news
.
id
}
key=
{
news
.
id
}
news=
{
news
}
news=
{
news
}
link=
{
`${PATHS.mediaInformation}/thu-vien-tai-lieu/${news.id}`
}
link=
{
`${PATHS.mediaInformation}/thu-vien-tai-lieu/${news.id}`
}
/>
/>
)
))
}
))
}
<
div
className=
"w-full flex justify-center mt-4"
>
<
div
className=
"w-full flex justify-center mt-4"
>
<
Pagination
<
Pagination
...
@@ -49,6 +56,8 @@ export default function Page() {
...
@@ -49,6 +56,8 @@ export default function Page() {
onGoToNextPage=
{
()
=>
setPage
(
Math
.
min
(
Number
(
allData
?.
responseData
.
totalPages
??
1
),
page
+
1
))
}
onGoToNextPage=
{
()
=>
setPage
(
Math
.
min
(
Number
(
allData
?.
responseData
.
totalPages
??
1
),
page
+
1
))
}
/>
/>
</
div
>
</
div
>
</>
)
}
</
div
>
</
div
>
</
main
>
</
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";
...
@@ -10,15 +10,16 @@ import Image from "next/image";
import
{
useGetNews
}
from
"@api/endpoints/news"
;
import
{
useGetNews
}
from
"@api/endpoints/news"
;
import
{
GetNewsResponseType
}
from
"@api/types/NewsPage.type"
;
import
{
GetNewsResponseType
}
from
"@api/types/NewsPage.type"
;
import
{
PATHS
}
from
"@constants/paths"
;
import
{
PATHS
}
from
"@constants/paths"
;
import
{
Spinner
}
from
"@components/ui/spinner"
;
export
default
function
Page
()
{
export
default
function
Page
()
{
const
[
submitSearch
]
=
useState
(
""
);
const
[
submitSearch
]
=
useState
(
""
);
const
[
page
,
setPage
]
=
useState
(
1
);
const
[
page
,
setPage
]
=
useState
(
1
);
const
pageSize
=
5
;
const
pageSize
=
5
;
const
{
data
:
allData
}
=
useGetNews
<
GetNewsResponseType
>
({
const
{
data
:
allData
,
isLoading
}
=
useGetNews
<
GetNewsResponseType
>
({
pageSize
:
String
(
pageSize
),
pageSize
:
String
(
pageSize
),
currentPage
:
String
(
page
),
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
(
return
(
<
div
className=
"min-h-screen container mx-auto p-4"
>
<
div
className=
"min-h-screen container mx-auto p-4"
>
...
@@ -29,16 +30,22 @@ export default function Page() {
...
@@ -29,16 +30,22 @@ export default function Page() {
{
/* Main content */
}
{
/* Main content */
}
<
main
className=
"lg:col-span-2 bg-background "
>
<
main
className=
"lg:col-span-2 bg-background "
>
<
div
className=
"pb-5 overflow-hidden"
>
<
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
>
<
p
className=
"text-center py-4"
>
Không có dữ liệu
</
p
>
)
:
(
)
:
(
allData
?.
responseData
.
rows
.
map
((
news
)
=>
(
<>
{
allData
?.
responseData
.
rows
.
map
((
news
)
=>
(
<
NewsContent
<
NewsContent
key=
{
news
.
id
}
key=
{
news
.
id
}
news=
{
news
}
news=
{
news
}
link=
{
`${PATHS.mediaInformation}/tin-doanh-nghiep/${news.id}`
}
link=
{
`${PATHS.mediaInformation}/tin-doanh-nghiep/${news.id}`
}
/>
/>
)
))
}
))
}
<
div
className=
"w-full flex justify-center mt-4"
>
<
div
className=
"w-full flex justify-center mt-4"
>
<
Pagination
<
Pagination
...
@@ -49,6 +56,8 @@ export default function Page() {
...
@@ -49,6 +56,8 @@ export default function Page() {
onGoToNextPage=
{
()
=>
setPage
(
Math
.
min
(
Number
(
allData
?.
responseData
.
totalPages
??
1
),
page
+
1
))
}
onGoToNextPage=
{
()
=>
setPage
(
Math
.
min
(
Number
(
allData
?.
responseData
.
totalPages
??
1
),
page
+
1
))
}
/>
/>
</
div
>
</
div
>
</>
)
}
</
div
>
</
div
>
</
main
>
</
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";
...
@@ -9,15 +9,16 @@ import Image from "next/image";
import
{
useGetNews
}
from
"@api/endpoints/news"
;
import
{
useGetNews
}
from
"@api/endpoints/news"
;
import
{
GetNewsResponseType
}
from
"@api/types/NewsPage.type"
;
import
{
GetNewsResponseType
}
from
"@api/types/NewsPage.type"
;
import
{
PATHS
}
from
"@constants/paths"
;
import
{
PATHS
}
from
"@constants/paths"
;
import
{
Spinner
}
from
"@components/ui/spinner"
;
export
default
function
Page
()
{
export
default
function
Page
()
{
const
[
submitSearch
]
=
useState
(
""
);
const
[
submitSearch
]
=
useState
(
""
);
const
[
page
,
setPage
]
=
useState
(
1
);
const
[
page
,
setPage
]
=
useState
(
1
);
const
pageSize
=
5
;
const
pageSize
=
5
;
const
{
data
:
allData
}
=
useGetNews
<
GetNewsResponseType
>
({
const
{
data
:
allData
,
isLoading
}
=
useGetNews
<
GetNewsResponseType
>
({
pageSize
:
String
(
pageSize
),
pageSize
:
String
(
pageSize
),
currentPage
:
String
(
page
),
currentPage
:
String
(
page
),
filters
:
submitSearch
?
`title @=
${
submitSearch
}
`
:
'category @=Tin kinh tế'
,
filters
:
submitSearch
?
`title @=
${
submitSearch
}
,category @=Tin kinh tế
`
:
'category @=Tin kinh tế'
,
});
});
return
(
return
(
<
div
className=
"min-h-screen container mx-auto p-4"
>
<
div
className=
"min-h-screen container mx-auto p-4"
>
...
@@ -28,16 +29,22 @@ export default function Page() {
...
@@ -28,16 +29,22 @@ export default function Page() {
{
/* Main content */
}
{
/* Main content */
}
<
main
className=
"lg:col-span-2 bg-background "
>
<
main
className=
"lg:col-span-2 bg-background "
>
<
div
className=
"pb-5 overflow-hidden"
>
<
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
>
<
p
className=
"text-center py-4"
>
Không có dữ liệu
</
p
>
)
:
(
)
:
(
allData
?.
responseData
.
rows
.
map
((
news
)
=>
(
<>
{
allData
?.
responseData
.
rows
.
map
((
news
)
=>
(
<
NewsContent
<
NewsContent
key=
{
news
.
id
}
key=
{
news
.
id
}
news=
{
news
}
news=
{
news
}
link=
{
`${PATHS.mediaInformation}/tin-kinh-te/${news.id}`
}
link=
{
`${PATHS.mediaInformation}/tin-kinh-te/${news.id}`
}
/>
/>
)
))
}
))
}
<
div
className=
"w-full flex justify-center mt-4"
>
<
div
className=
"w-full flex justify-center mt-4"
>
<
Pagination
<
Pagination
...
@@ -48,6 +55,8 @@ export default function Page() {
...
@@ -48,6 +55,8 @@ export default function Page() {
onGoToNextPage=
{
()
=>
setPage
(
Math
.
min
(
Number
(
allData
?.
responseData
.
totalPages
??
1
),
page
+
1
))
}
onGoToNextPage=
{
()
=>
setPage
(
Math
.
min
(
Number
(
allData
?.
responseData
.
totalPages
??
1
),
page
+
1
))
}
/>
/>
</
div
>
</
div
>
</>
)
}
</
div
>
</
div
>
</
main
>
</
main
>
...
...
src/app/(main)/thong-tin-truyen-thong/tin-vcci/page.tsx
View file @
74a04b88
...
@@ -11,12 +11,13 @@ import Image from "next/image";
...
@@ -11,12 +11,13 @@ import Image from "next/image";
import
{
useGetNews
}
from
"@api/endpoints/news"
;
import
{
useGetNews
}
from
"@api/endpoints/news"
;
import
{
PATHS
}
from
"@constants/paths"
;
import
{
PATHS
}
from
"@constants/paths"
;
import
{
GetNewsResponseType
}
from
"@api/types/NewsPage.type"
;
import
{
GetNewsResponseType
}
from
"@api/types/NewsPage.type"
;
import
{
Spinner
}
from
"@components/ui/spinner"
;
export
default
function
Page
()
{
export
default
function
Page
()
{
const
[
submitSearch
,
setSubmitSearch
]
=
useState
(
""
);
const
[
submitSearch
,
setSubmitSearch
]
=
useState
(
""
);
const
[
page
,
setPage
]
=
useState
(
1
);
const
[
page
,
setPage
]
=
useState
(
1
);
const
pageSize
=
5
;
const
pageSize
=
5
;
const
{
data
:
allData
}
=
useGetNews
<
GetNewsResponseType
>
({
const
{
data
:
allData
,
isLoading
}
=
useGetNews
<
GetNewsResponseType
>
({
pageSize
:
String
(
pageSize
),
pageSize
:
String
(
pageSize
),
currentPage
:
String
(
page
),
currentPage
:
String
(
page
),
filters
:
submitSearch
?
`title @=
${
submitSearch
}
`
:
undefined
,
filters
:
submitSearch
?
`title @=
${
submitSearch
}
`
:
undefined
,
...
@@ -30,17 +31,22 @@ export default function Page() {
...
@@ -30,17 +31,22 @@ export default function Page() {
{
/* Main content */
}
{
/* Main content */
}
<
main
className=
"lg:col-span-2 bg-background "
>
<
main
className=
"lg:col-span-2 bg-background "
>
<
div
className=
"pb-5 overflow-hidden"
>
<
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
>
<
p
className=
"text-center py-4"
>
Không có dữ liệu
</
p
>
)
:
(
)
:
(
allData
?.
responseData
.
rows
.
map
((
news
)
=>
(
<>
{
allData
?.
responseData
.
rows
.
map
((
news
)
=>
(
<
NewsContent
<
NewsContent
key=
{
news
.
id
}
key=
{
news
.
id
}
news=
{
news
}
news=
{
news
}
link=
{
`${PATHS.mediaInformation}/tin-vcci/${news.id}`
}
link=
{
`${PATHS.mediaInformation}/tin-vcci/${news.id}`
}
/>
/>
)))
))
}
}
<
div
className=
"w-full flex justify-center mt-4"
>
<
div
className=
"w-full flex justify-center mt-4"
>
<
Pagination
<
Pagination
...
@@ -51,6 +57,8 @@ export default function Page() {
...
@@ -51,6 +57,8 @@ export default function Page() {
onGoToNextPage=
{
()
=>
setPage
(
Math
.
min
(
Number
(
allData
?.
responseData
.
totalPages
??
1
),
page
+
1
))
}
onGoToNextPage=
{
()
=>
setPage
(
Math
.
min
(
Number
(
allData
?.
responseData
.
totalPages
??
1
),
page
+
1
))
}
/>
/>
</
div
>
</
div
>
</>
)
}
</
div
>
</
div
>
</
main
>
</
main
>
...
...
src/app/(main)/xuc-tien-thuong-mai/[id]/page.tsx
View file @
74a04b88
...
@@ -8,6 +8,7 @@ import { useGetNewsId } from '@/api/endpoints/news';
...
@@ -8,6 +8,7 @@ import { useGetNewsId } from '@/api/endpoints/news';
import
parse
from
"html-react-parser"
;
import
parse
from
"html-react-parser"
;
import
{
useParams
}
from
'next/navigation'
import
{
useParams
}
from
'next/navigation'
import
{
GetNewsDetailResponseType
}
from
'@lib/types/news-detail-response-data'
;
import
{
GetNewsDetailResponseType
}
from
'@lib/types/news-detail-response-data'
;
import
{
Spinner
}
from
"@components/ui/spinner"
;
// ...existing code...
// ...existing code...
const
Page
:
React
.
FC
=
()
=>
{
const
Page
:
React
.
FC
=
()
=>
{
const
{
id
}
=
useParams
()
const
{
id
}
=
useParams
()
...
@@ -20,11 +21,20 @@ const Page: React.FC = () => {
...
@@ -20,11 +21,20 @@ const Page: React.FC = () => {
<
div
className=
"grid grid-cols-1 lg:grid-cols-3 gap-6"
>
<
div
className=
"grid grid-cols-1 lg:grid-cols-3 gap-6"
>
{
/* Main content */
}
{
/* Main content */
}
<
main
className=
"lg:col-span-2 bg-white border rounded-md p-6"
>
<
main
className=
"lg:col-span-2 bg-white border rounded-md p-6"
>
{
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'
>
<
div
className=
'pb-5 text-primary text-2xl leading-normal font-medium'
>
{
data
?.
responseData
?.
title
}
{
data
?.
responseData
?.
title
}
</
div
>
</
div
>
<
hr
className=
"py-2"
/>
<
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
>
</
main
>
{
/* Sidebar */
}
{
/* 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';
...
@@ -8,6 +8,7 @@ import { useGetNewsId } from '@/api/endpoints/news';
import
parse
from
"html-react-parser"
;
import
parse
from
"html-react-parser"
;
import
{
useParams
}
from
'next/navigation'
import
{
useParams
}
from
'next/navigation'
import
{
GetNewsDetailResponseType
}
from
'@lib/types/news-detail-response-data'
;
import
{
GetNewsDetailResponseType
}
from
'@lib/types/news-detail-response-data'
;
import
{
Spinner
}
from
"@components/ui/spinner"
;
// ...existing code...
// ...existing code...
const
Page
:
React
.
FC
=
()
=>
{
const
Page
:
React
.
FC
=
()
=>
{
const
{
id
}
=
useParams
()
const
{
id
}
=
useParams
()
...
@@ -20,11 +21,22 @@ const Page: React.FC = () => {
...
@@ -20,11 +21,22 @@ const Page: React.FC = () => {
<
div
className=
"grid grid-cols-1 lg:grid-cols-3 gap-6"
>
<
div
className=
"grid grid-cols-1 lg:grid-cols-3 gap-6"
>
{
/* Main content */
}
{
/* Main content */
}
<
main
className=
"lg:col-span-2 bg-white border rounded-md p-6"
>
<
main
className=
"lg:col-span-2 bg-white border rounded-md p-6"
>
{
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'
>
<
div
className=
'pb-5 text-primary text-2xl leading-normal font-medium'
>
{
data
?.
responseData
?.
title
}
{
data
?.
responseData
?.
title
}
</
div
>
</
div
>
<
hr
className=
"py-2"
/>
<
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
>
</
main
>
{
/* Sidebar */
}
{
/* 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";
...
@@ -9,12 +9,13 @@ import Image from "next/image";
import
{
useGetNews
}
from
"@api/endpoints/news"
;
import
{
useGetNews
}
from
"@api/endpoints/news"
;
import
{
GetNewsResponseType
}
from
"@api/types/NewsPage.type"
;
import
{
GetNewsResponseType
}
from
"@api/types/NewsPage.type"
;
import
{
PATHS
}
from
"@constants/paths"
;
import
{
PATHS
}
from
"@constants/paths"
;
import
{
Spinner
}
from
"@components/ui/spinner"
;
export
default
function
Page
()
{
export
default
function
Page
()
{
const
[
submitSearch
]
=
useState
(
""
);
const
[
submitSearch
]
=
useState
(
""
);
const
[
page
,
setPage
]
=
useState
(
1
);
const
[
page
,
setPage
]
=
useState
(
1
);
const
pageSize
=
5
;
const
pageSize
=
5
;
const
{
data
:
allData
}
=
useGetNews
<
GetNewsResponseType
>
({
const
{
data
:
allData
,
isLoading
}
=
useGetNews
<
GetNewsResponseType
>
({
pageSize
:
String
(
pageSize
),
pageSize
:
String
(
pageSize
),
currentPage
:
String
(
page
),
currentPage
:
String
(
page
),
// filters: submitSearch ? `title @=${submitSearch}` : undefined,
// filters: submitSearch ? `title @=${submitSearch}` : undefined,
...
@@ -29,6 +30,15 @@ export default function Page() {
...
@@ -29,6 +30,15 @@ export default function Page() {
{
/* Main content */
}
{
/* Main content */
}
<
main
className=
"lg:col-span-2 bg-background "
>
<
main
className=
"lg:col-span-2 bg-background "
>
<
div
className=
"pb-5 overflow-hidden"
>
<
div
className=
"pb-5 overflow-hidden"
>
{
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
)
=>
(
{
allData
?.
responseData
.
rows
.
map
((
news
)
=>
(
<
NewsContent
key=
{
news
.
id
}
news=
{
news
}
link=
{
`${PATHS.tradePromotion}/${news.id}`
}
/>
<
NewsContent
key=
{
news
.
id
}
news=
{
news
}
link=
{
`${PATHS.tradePromotion}/${news.id}`
}
/>
))
}
))
}
...
@@ -49,6 +59,8 @@ export default function Page() {
...
@@ -49,6 +59,8 @@ export default function Page() {
}
}
/>
/>
</
div
>
</
div
>
</>
)
}
</
div
>
</
div
>
</
main
>
</
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';
...
@@ -8,6 +8,7 @@ import { useGetNewsId } from '@/api/endpoints/news';
import
parse
from
"html-react-parser"
;
import
parse
from
"html-react-parser"
;
import
{
useParams
}
from
'next/navigation'
import
{
useParams
}
from
'next/navigation'
import
{
GetNewsDetailResponseType
}
from
'@lib/types/news-detail-response-data'
;
import
{
GetNewsDetailResponseType
}
from
'@lib/types/news-detail-response-data'
;
import
{
Spinner
}
from
"@components/ui/spinner"
;
// ...existing code...
// ...existing code...
const
Page
:
React
.
FC
=
()
=>
{
const
Page
:
React
.
FC
=
()
=>
{
const
{
id
}
=
useParams
()
const
{
id
}
=
useParams
()
...
@@ -20,11 +21,22 @@ const Page: React.FC = () => {
...
@@ -20,11 +21,22 @@ const Page: React.FC = () => {
<
div
className=
"grid grid-cols-1 lg:grid-cols-3 gap-6"
>
<
div
className=
"grid grid-cols-1 lg:grid-cols-3 gap-6"
>
{
/* Main content */
}
{
/* Main content */
}
<
main
className=
"lg:col-span-2 bg-white border rounded-md p-6"
>
<
main
className=
"lg:col-span-2 bg-white border rounded-md p-6"
>
{
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'
>
<
div
className=
'pb-5 text-primary text-2xl leading-normal font-medium'
>
{
data
?.
responseData
?.
title
}
{
data
?.
responseData
?.
title
}
</
div
>
</
div
>
<
hr
className=
"py-2"
/>
<
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
>
</
main
>
{
/* Sidebar */
}
{
/* 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";
...
@@ -8,12 +8,13 @@ import Image from "next/image";
import
{
useGetNews
}
from
"@api/endpoints/news"
;
import
{
useGetNews
}
from
"@api/endpoints/news"
;
import
{
GetNewsResponseType
}
from
"@api/types/NewsPage.type"
;
import
{
GetNewsResponseType
}
from
"@api/types/NewsPage.type"
;
import
{
PATHS
}
from
"@constants/paths"
;
import
{
PATHS
}
from
"@constants/paths"
;
import
{
Spinner
}
from
"@components/ui/spinner"
;
export
default
function
Page
()
{
export
default
function
Page
()
{
const
[
submitSearch
]
=
useState
(
""
);
const
[
submitSearch
]
=
useState
(
""
);
const
[
page
,
setPage
]
=
useState
(
1
);
const
[
page
,
setPage
]
=
useState
(
1
);
const
pageSize
=
5
;
const
pageSize
=
5
;
const
{
data
:
allData
}
=
useGetNews
<
GetNewsResponseType
>
({
const
{
data
:
allData
,
isLoading
}
=
useGetNews
<
GetNewsResponseType
>
({
pageSize
:
String
(
pageSize
),
pageSize
:
String
(
pageSize
),
currentPage
:
String
(
page
),
currentPage
:
String
(
page
),
// filters: submitSearch ? `title @=${submitSearch}` : undefined,
// filters: submitSearch ? `title @=${submitSearch}` : undefined,
...
@@ -28,6 +29,15 @@ export default function Page() {
...
@@ -28,6 +29,15 @@ export default function Page() {
{
/* Main content */
}
{
/* Main content */
}
<
main
className=
"lg:col-span-2 bg-background "
>
<
main
className=
"lg:col-span-2 bg-background "
>
<
div
className=
"pb-5 overflow-hidden"
>
<
div
className=
"pb-5 overflow-hidden"
>
{
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
)
=>
(
{
allData
?.
responseData
.
rows
.
map
((
news
)
=>
(
<
NewsContent
<
NewsContent
key=
{
news
.
id
}
key=
{
news
.
id
}
...
@@ -52,6 +62,8 @@ export default function Page() {
...
@@ -52,6 +62,8 @@ export default function Page() {
}
}
/>
/>
</
div
>
</
div
>
</>
)
}
</
div
>
</
div
>
</
main
>
</
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';
...
@@ -8,6 +8,7 @@ import { useGetNewsId } from '@/api/endpoints/news';
import
parse
from
"html-react-parser"
;
import
parse
from
"html-react-parser"
;
import
{
useParams
}
from
'next/navigation'
import
{
useParams
}
from
'next/navigation'
import
{
GetNewsDetailResponseType
}
from
'@lib/types/news-detail-response-data'
;
import
{
GetNewsDetailResponseType
}
from
'@lib/types/news-detail-response-data'
;
import
{
Spinner
}
from
"@components/ui/spinner"
;
// ...existing code...
// ...existing code...
const
Page
:
React
.
FC
=
()
=>
{
const
Page
:
React
.
FC
=
()
=>
{
const
{
id
}
=
useParams
()
const
{
id
}
=
useParams
()
...
@@ -20,11 +21,22 @@ const Page: React.FC = () => {
...
@@ -20,11 +21,22 @@ const Page: React.FC = () => {
<
div
className=
"grid grid-cols-1 lg:grid-cols-3 gap-6"
>
<
div
className=
"grid grid-cols-1 lg:grid-cols-3 gap-6"
>
{
/* Main content */
}
{
/* Main content */
}
<
main
className=
"lg:col-span-2 bg-white border rounded-md p-6"
>
<
main
className=
"lg:col-span-2 bg-white border rounded-md p-6"
>
{
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'
>
<
div
className=
'pb-5 text-primary text-2xl leading-normal font-medium'
>
{
data
?.
responseData
?.
title
}
{
data
?.
responseData
?.
title
}
</
div
>
</
div
>
<
hr
className=
"py-2"
/>
<
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
>
</
main
>
{
/* Sidebar */
}
{
/* 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";
...
@@ -9,12 +9,13 @@ import EventCalendar from "@app/dai-dien-gioi-chu/components/event-calendar";
import
{
useGetNews
}
from
"@api/endpoints/news"
;
import
{
useGetNews
}
from
"@api/endpoints/news"
;
import
{
GetNewsResponseType
}
from
"@api/types/NewsPage.type"
;
import
{
GetNewsResponseType
}
from
"@api/types/NewsPage.type"
;
import
{
PATHS
}
from
"@constants/paths"
;
import
{
PATHS
}
from
"@constants/paths"
;
import
{
Spinner
}
from
"@components/ui/spinner"
;
export
default
function
Page
()
{
export
default
function
Page
()
{
const
[
submitSearch
]
=
useState
(
""
);
const
[
submitSearch
]
=
useState
(
""
);
const
[
page
,
setPage
]
=
useState
(
1
);
const
[
page
,
setPage
]
=
useState
(
1
);
const
pageSize
=
5
;
const
pageSize
=
5
;
const
{
data
:
allData
}
=
useGetNews
<
GetNewsResponseType
>
({
const
{
data
:
allData
,
isLoading
}
=
useGetNews
<
GetNewsResponseType
>
({
pageSize
:
String
(
pageSize
),
pageSize
:
String
(
pageSize
),
currentPage
:
String
(
page
),
currentPage
:
String
(
page
),
// filters: submitSearch ? `title @=${submitSearch}` : undefined,
// filters: submitSearch ? `title @=${submitSearch}` : undefined,
...
@@ -29,6 +30,15 @@ export default function Page() {
...
@@ -29,6 +30,15 @@ export default function Page() {
{
/* Main content */
}
{
/* Main content */
}
<
main
className=
"lg:col-span-2 bg-background "
>
<
main
className=
"lg:col-span-2 bg-background "
>
<
div
className=
"pb-5 overflow-hidden"
>
<
div
className=
"pb-5 overflow-hidden"
>
{
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
)
=>
(
{
allData
?.
responseData
.
rows
.
map
((
news
)
=>
(
<
NewsContent
<
NewsContent
key=
{
news
.
id
}
key=
{
news
.
id
}
...
@@ -53,6 +63,8 @@ export default function Page() {
...
@@ -53,6 +63,8 @@ export default function Page() {
}
}
/>
/>
</
div
>
</
div
>
</>
)
}
</
div
>
</
div
>
</
main
>
</
main
>
...
...
src/app/(main)/xuc-tien-thuong-mai/page.tsx
View file @
74a04b88
...
@@ -8,12 +8,13 @@ import Image from "next/image";
...
@@ -8,12 +8,13 @@ import Image from "next/image";
import
{
useGetNews
}
from
"@api/endpoints/news"
;
import
{
useGetNews
}
from
"@api/endpoints/news"
;
import
{
GetNewsResponseType
}
from
"@api/types/NewsPage.type"
;
import
{
GetNewsResponseType
}
from
"@api/types/NewsPage.type"
;
import
{
PATHS
}
from
"@constants/paths"
;
import
{
PATHS
}
from
"@constants/paths"
;
import
{
Spinner
}
from
"@components/ui/spinner"
;
export
default
function
Page
()
{
export
default
function
Page
()
{
const
[
submitSearch
]
=
useState
(
""
);
const
[
submitSearch
]
=
useState
(
""
);
const
[
page
,
setPage
]
=
useState
(
1
);
const
[
page
,
setPage
]
=
useState
(
1
);
const
pageSize
=
5
;
const
pageSize
=
5
;
const
{
data
:
allData
}
=
useGetNews
<
GetNewsResponseType
>
({
const
{
data
:
allData
,
isLoading
}
=
useGetNews
<
GetNewsResponseType
>
({
pageSize
:
String
(
pageSize
),
pageSize
:
String
(
pageSize
),
currentPage
:
String
(
page
),
currentPage
:
String
(
page
),
filters
:
submitSearch
?
`title @=
${
submitSearch
}
`
:
undefined
,
filters
:
submitSearch
?
`title @=
${
submitSearch
}
`
:
undefined
,
...
@@ -27,6 +28,13 @@ export default function Page() {
...
@@ -27,6 +28,13 @@ export default function Page() {
{
/* Main content */
}
{
/* Main content */
}
<
main
className=
"lg:col-span-2 bg-background "
>
<
main
className=
"lg:col-span-2 bg-background "
>
<
div
className=
"pb-5 overflow-hidden"
>
<
div
className=
"pb-5 overflow-hidden"
>
{
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
)
=>
(
{
allData
?.
responseData
.
rows
.
map
((
news
)
=>
(
<
NewsContent
key=
{
news
.
id
}
news=
{
news
}
link=
{
`${PATHS.tradePromotion}/${news.id}`
}
/>
<
NewsContent
key=
{
news
.
id
}
news=
{
news
}
link=
{
`${PATHS.tradePromotion}/${news.id}`
}
/>
))
}
))
}
...
@@ -47,6 +55,8 @@ export default function Page() {
...
@@ -47,6 +55,8 @@ export default function Page() {
}
}
/>
/>
</
div
>
</
div
>
</>
)
}
</
div
>
</
div
>
</
main
>
</
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