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
5ca290c8
Commit
5ca290c8
authored
Nov 05, 2025
by
Vũ Đình Nguyên
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'tumlumtumla' into 'develop'
Tumlumtumla See merge request
!9
parents
cbfd9322
695425f5
Changes
56
Hide whitespace changes
Inline
Side-by-side
Showing
56 changed files
with
2197 additions
and
409 deletions
+2197
-409
orval.config.ts
orval.config.ts
+2
-1
fallback.png
public/fallback.png
+0
-0
news-page-config.ts
src/api/endpoints/news-page-config.ts
+930
-0
index.ts
src/api/models/index.ts
+1
-0
putNewsPageConfigCategoryIdBody.ts
src/api/models/putNewsPageConfigCategoryIdBody.ts
+11
-0
event.ts
src/api/types/event.ts
+64
-2
page.tsx
src/app/(main)/(home)/[id]/page.tsx
+1
-1
index.tsx
src/app/(main)/(home)/components/card-event/index.tsx
+4
-0
index.tsx
src/app/(main)/(home)/components/card-news/index.tsx
+6
-1
page.tsx
src/app/(main)/(home)/page.tsx
+11
-2
footer.tsx
src/app/(main)/_lib/layout/footer.tsx
+2
-2
header.tsx
src/app/(main)/_lib/layout/header.tsx
+28
-19
page.tsx
src/app/(main)/dai-dien-gioi-chu/chu-de/[id]/page.tsx
+4
-0
page.tsx
src/app/(main)/dai-dien-gioi-chu/chu-de/page.tsx
+32
-21
index.tsx
...p/(main)/dai-dien-gioi-chu/components/card-news/index.tsx
+24
-8
sampleHtml.ts
src/app/(main)/dai-dien-gioi-chu/lib/sampleHtml.ts
+1
-1
page.tsx
...app/(main)/dai-dien-gioi-chu/tap-huan-nsdld/[id]/page.tsx
+4
-0
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/[id]/page.tsx
+15
-7
page.tsx
src/app/(main)/dai-dien-gioi-chu/tin-lien-quan/page.tsx
+27
-16
page.tsx
src/app/(main)/hoat-dong/dao-tao/[id]/page.tsx
+4
-0
page.tsx
src/app/(main)/hoat-dong/dao-tao/page.tsx
+26
-16
page.tsx
src/app/(main)/hoat-dong/page.tsx
+1
-1
page.tsx
src/app/(main)/hoat-dong/su-kien/[id]/page.tsx
+18
-3
page.tsx
src/app/(main)/hoat-dong/su-kien/page.tsx
+30
-16
page.tsx
src/app/(main)/hoi-vien/ket-noi-hoi-vien/page.tsx
+32
-22
page.tsx
src/app/(main)/hoi-vien/tin-hoi-vien/page.tsx
+30
-20
page.tsx
src/app/(main)/search/page.tsx
+112
-0
mock-data.ts
src/app/(main)/site-map/_lib/mock-data.ts
+94
-0
page.tsx
src/app/(main)/site-map/page.tsx
+103
-0
page.tsx
...app/(main)/thong-tin-truyen-thong/chuyen-de/[id]/page.tsx
+4
-0
page.tsx
src/app/(main)/thong-tin-truyen-thong/chuyen-de/page.tsx
+32
-20
page.tsx
src/app/(main)/thong-tin-truyen-thong/page.tsx
+1
-1
page.tsx
...yen-thong/thong-tin-chinh-sach-va-phap-luat/[id]/page.tsx
+4
-0
page.tsx
...n-truyen-thong/thong-tin-chinh-sach-va-phap-luat/page.tsx
+14
-11
page.tsx
...n)/thong-tin-truyen-thong/thu-vien-tai-lieu/[id]/page.tsx
+4
-0
page.tsx
.../(main)/thong-tin-truyen-thong/thu-vien-tai-lieu/page.tsx
+32
-20
page.tsx
...in)/thong-tin-truyen-thong/tin-doanh-nghiep/[id]/page.tsx
+4
-0
page.tsx
...p/(main)/thong-tin-truyen-thong/tin-doanh-nghiep/page.tsx
+32
-20
page.tsx
...p/(main)/thong-tin-truyen-thong/tin-kinh-te/[id]/page.tsx
+4
-0
page.tsx
src/app/(main)/thong-tin-truyen-thong/tin-kinh-te/page.tsx
+32
-20
page.tsx
src/app/(main)/thong-tin-truyen-thong/tin-vcci/[id]/page.tsx
+4
-0
page.tsx
src/app/(main)/thong-tin-truyen-thong/tin-vcci/page.tsx
+34
-22
page.tsx
src/app/(main)/xuat-xu-hang-hoa/page.tsx
+1
-1
page.tsx
src/app/(main)/xuc-tien-thuong-mai/[id]/page.tsx
+15
-1
page.tsx
...main)/xuc-tien-thuong-mai/co-hoi-kinh-doanh/[id]/page.tsx
+17
-1
page.tsx
...app/(main)/xuc-tien-thuong-mai/co-hoi-kinh-doanh/page.tsx
+34
-21
page.tsx
...main)/xuc-tien-thuong-mai/ho-tro-kinh-doanh/[id]/page.tsx
+17
-1
page.tsx
...app/(main)/xuc-tien-thuong-mai/ho-tro-kinh-doanh/page.tsx
+38
-25
page.tsx
...)/xuc-tien-thuong-mai/moi-truong-kinh-doanh/[id]/page.tsx
+17
-1
page.tsx
...(main)/xuc-tien-thuong-mai/moi-truong-kinh-doanh/page.tsx
+38
-25
page.tsx
src/app/(main)/xuc-tien-thuong-mai/page.tsx
+29
-19
index.tsx
src/components/base/card-news/index.tsx
+24
-7
AppEditorContent.tsx
src/components/shared/editor-content/AppEditorContent.tsx
+37
-14
loading-state.tsx
src/components/ui/loading-state.tsx
+49
-0
common.ts
src/lib/types/common.ts
+33
-0
No files found.
orval.config.ts
View file @
5ca290c8
...
...
@@ -79,7 +79,8 @@ const orvalConfig = async () => {
'UserHistory'
,
'Approvals'
,
'News'
,
'Category'
'Category'
,
'NewsPageConfig'
,
]
}
}
...
...
public/fallback.png
0 → 100644
View file @
5ca290c8
498 Bytes
src/api/endpoints/news-page-config.ts
0 → 100644
View file @
5ca290c8
/**
* Generated by orval v8.0.0-rc.0 🍺
* Do not edit manually.
* VCCI
* Coded by Meu TEAM
* OpenAPI spec version: 1.0.0
*/
import
{
useInfiniteQuery
,
useMutation
,
useQuery
}
from
'@tanstack/react-query'
;
import
type
{
DataTag
,
DefinedInitialDataOptions
,
DefinedUseInfiniteQueryResult
,
DefinedUseQueryResult
,
InfiniteData
,
MutationFunction
,
QueryClient
,
QueryFunction
,
QueryKey
,
UndefinedInitialDataOptions
,
UseInfiniteQueryOptions
,
UseInfiniteQueryResult
,
UseMutationOptions
,
UseMutationResult
,
UseQueryOptions
,
UseQueryResult
}
from
'@tanstack/react-query'
;
import
type
{
PutNewsPageConfigCategoryIdBody
,
Response
}
from
'../models'
;
import
{
useCustomClient
}
from
'../mutator/custom-client'
;
import
type
{
ErrorType
,
BodyType
}
from
'../mutator/custom-client'
;
type
SecondParameter
<
T
extends
(...
args
:
never
)
=>
unknown
>
=
Parameters
<
T
>
[
1
];
/**
* Get page config category by id
*/
export
type
getNewsPageConfigCategoryIdResponse200
=
{
data
:
Response
status
:
200
}
export
type
getNewsPageConfigCategoryIdResponseSuccess
=
(
getNewsPageConfigCategoryIdResponse200
)
&
{
headers
:
Headers
;
};
;
export
type
getNewsPageConfigCategoryIdResponse
=
(
getNewsPageConfigCategoryIdResponseSuccess
)
export
const
getGetNewsPageConfigCategoryIdUrl
=
(
id
:
string
,)
=>
{
return
`/newsPageConfig/category/
${
id
}
`
}
export
const
getNewsPageConfigCategoryId
=
async
(
id
:
string
,
options
?:
RequestInit
):
Promise
<
getNewsPageConfigCategoryIdResponse
>
=>
{
return
useCustomClient
<
getNewsPageConfigCategoryIdResponse
>
(
getGetNewsPageConfigCategoryIdUrl
(
id
),
{
...
options
,
method
:
'GET'
}
);}
export
const
getGetNewsPageConfigCategoryIdInfiniteQueryKey
=
(
id
?:
string
,)
=>
{
return
[
'infinite'
,
`/newsPageConfig/category/
${
id
}
`
]
as
const
;
}
export
const
getGetNewsPageConfigCategoryIdQueryKey
=
(
id
?:
string
,)
=>
{
return
[
`/newsPageConfig/category/
${
id
}
`
]
as
const
;
}
export
const
getGetNewsPageConfigCategoryIdInfiniteQueryOptions
=
<
TData
=
InfiniteData
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfigCategoryId
>>>
,
TError
=
ErrorType
<
unknown
>>
(
id
:
string
,
options
?:
{
query
?:
Partial
<
UseInfiniteQueryOptions
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfigCategoryId
>>
,
TError
,
TData
>>
,
request
?:
SecondParameter
<
typeof
useCustomClient
>
}
)
=>
{
const
{
query
:
queryOptions
,
request
:
requestOptions
}
=
options
??
{};
const
queryKey
=
queryOptions
?.
queryKey
??
getGetNewsPageConfigCategoryIdInfiniteQueryKey
(
id
);
const
queryFn
:
QueryFunction
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfigCategoryId
>>>
=
({
signal
})
=>
getNewsPageConfigCategoryId
(
id
,
{
signal
,
...
requestOptions
});
return
{
queryKey
,
queryFn
,
enabled
:
!!
(
id
),
...
queryOptions
}
as
UseInfiniteQueryOptions
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfigCategoryId
>>
,
TError
,
TData
>
&
{
queryKey
:
DataTag
<
QueryKey
,
TData
,
TError
>
}
}
export
type
GetNewsPageConfigCategoryIdInfiniteQueryResult
=
NonNullable
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfigCategoryId
>>>
export
type
GetNewsPageConfigCategoryIdInfiniteQueryError
=
ErrorType
<
unknown
>
export
function
useGetNewsPageConfigCategoryIdInfinite
<
TData
=
InfiniteData
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfigCategoryId
>>>
,
TError
=
ErrorType
<
unknown
>>
(
id
:
string
,
options
:
{
query
:
Partial
<
UseInfiniteQueryOptions
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfigCategoryId
>>
,
TError
,
TData
>>
&
Pick
<
DefinedInitialDataOptions
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfigCategoryId
>>
,
TError
,
Awaited
<
ReturnType
<
typeof
getNewsPageConfigCategoryId
>>
>
,
'initialData'
>
,
request
?:
SecondParameter
<
typeof
useCustomClient
>
}
,
queryClient
?:
QueryClient
):
DefinedUseInfiniteQueryResult
<
TData
,
TError
>
&
{
queryKey
:
DataTag
<
QueryKey
,
TData
,
TError
>
}
export
function
useGetNewsPageConfigCategoryIdInfinite
<
TData
=
InfiniteData
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfigCategoryId
>>>
,
TError
=
ErrorType
<
unknown
>>
(
id
:
string
,
options
?:
{
query
?:
Partial
<
UseInfiniteQueryOptions
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfigCategoryId
>>
,
TError
,
TData
>>
&
Pick
<
UndefinedInitialDataOptions
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfigCategoryId
>>
,
TError
,
Awaited
<
ReturnType
<
typeof
getNewsPageConfigCategoryId
>>
>
,
'initialData'
>
,
request
?:
SecondParameter
<
typeof
useCustomClient
>
}
,
queryClient
?:
QueryClient
):
UseInfiniteQueryResult
<
TData
,
TError
>
&
{
queryKey
:
DataTag
<
QueryKey
,
TData
,
TError
>
}
export
function
useGetNewsPageConfigCategoryIdInfinite
<
TData
=
InfiniteData
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfigCategoryId
>>>
,
TError
=
ErrorType
<
unknown
>>
(
id
:
string
,
options
?:
{
query
?:
Partial
<
UseInfiniteQueryOptions
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfigCategoryId
>>
,
TError
,
TData
>>
,
request
?:
SecondParameter
<
typeof
useCustomClient
>
}
,
queryClient
?:
QueryClient
):
UseInfiniteQueryResult
<
TData
,
TError
>
&
{
queryKey
:
DataTag
<
QueryKey
,
TData
,
TError
>
}
export
function
useGetNewsPageConfigCategoryIdInfinite
<
TData
=
InfiniteData
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfigCategoryId
>>>
,
TError
=
ErrorType
<
unknown
>>
(
id
:
string
,
options
?:
{
query
?:
Partial
<
UseInfiniteQueryOptions
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfigCategoryId
>>
,
TError
,
TData
>>
,
request
?:
SecondParameter
<
typeof
useCustomClient
>
}
,
queryClient
?:
QueryClient
):
UseInfiniteQueryResult
<
TData
,
TError
>
&
{
queryKey
:
DataTag
<
QueryKey
,
TData
,
TError
>
}
{
const
queryOptions
=
getGetNewsPageConfigCategoryIdInfiniteQueryOptions
(
id
,
options
)
const
query
=
useInfiniteQuery
(
queryOptions
,
queryClient
)
as
UseInfiniteQueryResult
<
TData
,
TError
>
&
{
queryKey
:
DataTag
<
QueryKey
,
TData
,
TError
>
};
query
.
queryKey
=
queryOptions
.
queryKey
;
return
query
;
}
export
const
prefetchGetNewsPageConfigCategoryIdInfiniteQuery
=
async
<
TData
=
Awaited
<
ReturnType
<
typeof
getNewsPageConfigCategoryId
>>
,
TError
=
ErrorType
<
unknown
>>
(
queryClient
:
QueryClient
,
id
:
string
,
options
?:
{
query
?:
Partial
<
UseInfiniteQueryOptions
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfigCategoryId
>>
,
TError
,
TData
>>
,
request
?:
SecondParameter
<
typeof
useCustomClient
>
}
):
Promise
<
QueryClient
>
=>
{
const
queryOptions
=
getGetNewsPageConfigCategoryIdInfiniteQueryOptions
(
id
,
options
)
await
queryClient
.
prefetchInfiniteQuery
(
queryOptions
);
return
queryClient
;
}
export
const
getGetNewsPageConfigCategoryIdQueryOptions
=
<
TData
=
Awaited
<
ReturnType
<
typeof
getNewsPageConfigCategoryId
>>
,
TError
=
ErrorType
<
unknown
>>
(
id
:
string
,
options
?:
{
query
?:
Partial
<
UseQueryOptions
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfigCategoryId
>>
,
TError
,
TData
>>
,
request
?:
SecondParameter
<
typeof
useCustomClient
>
}
)
=>
{
const
{
query
:
queryOptions
,
request
:
requestOptions
}
=
options
??
{};
const
queryKey
=
queryOptions
?.
queryKey
??
getGetNewsPageConfigCategoryIdQueryKey
(
id
);
const
queryFn
:
QueryFunction
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfigCategoryId
>>>
=
({
signal
})
=>
getNewsPageConfigCategoryId
(
id
,
{
signal
,
...
requestOptions
});
return
{
queryKey
,
queryFn
,
enabled
:
!!
(
id
),
...
queryOptions
}
as
UseQueryOptions
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfigCategoryId
>>
,
TError
,
TData
>
&
{
queryKey
:
DataTag
<
QueryKey
,
TData
,
TError
>
}
}
export
type
GetNewsPageConfigCategoryIdQueryResult
=
NonNullable
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfigCategoryId
>>>
export
type
GetNewsPageConfigCategoryIdQueryError
=
ErrorType
<
unknown
>
export
function
useGetNewsPageConfigCategoryId
<
TData
=
Awaited
<
ReturnType
<
typeof
getNewsPageConfigCategoryId
>>
,
TError
=
ErrorType
<
unknown
>>
(
id
:
string
,
options
:
{
query
:
Partial
<
UseQueryOptions
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfigCategoryId
>>
,
TError
,
TData
>>
&
Pick
<
DefinedInitialDataOptions
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfigCategoryId
>>
,
TError
,
Awaited
<
ReturnType
<
typeof
getNewsPageConfigCategoryId
>>
>
,
'initialData'
>
,
request
?:
SecondParameter
<
typeof
useCustomClient
>
}
,
queryClient
?:
QueryClient
):
DefinedUseQueryResult
<
TData
,
TError
>
&
{
queryKey
:
DataTag
<
QueryKey
,
TData
,
TError
>
}
export
function
useGetNewsPageConfigCategoryId
<
TData
=
Awaited
<
ReturnType
<
typeof
getNewsPageConfigCategoryId
>>
,
TError
=
ErrorType
<
unknown
>>
(
id
:
string
,
options
?:
{
query
?:
Partial
<
UseQueryOptions
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfigCategoryId
>>
,
TError
,
TData
>>
&
Pick
<
UndefinedInitialDataOptions
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfigCategoryId
>>
,
TError
,
Awaited
<
ReturnType
<
typeof
getNewsPageConfigCategoryId
>>
>
,
'initialData'
>
,
request
?:
SecondParameter
<
typeof
useCustomClient
>
}
,
queryClient
?:
QueryClient
):
UseQueryResult
<
TData
,
TError
>
&
{
queryKey
:
DataTag
<
QueryKey
,
TData
,
TError
>
}
export
function
useGetNewsPageConfigCategoryId
<
TData
=
Awaited
<
ReturnType
<
typeof
getNewsPageConfigCategoryId
>>
,
TError
=
ErrorType
<
unknown
>>
(
id
:
string
,
options
?:
{
query
?:
Partial
<
UseQueryOptions
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfigCategoryId
>>
,
TError
,
TData
>>
,
request
?:
SecondParameter
<
typeof
useCustomClient
>
}
,
queryClient
?:
QueryClient
):
UseQueryResult
<
TData
,
TError
>
&
{
queryKey
:
DataTag
<
QueryKey
,
TData
,
TError
>
}
export
function
useGetNewsPageConfigCategoryId
<
TData
=
Awaited
<
ReturnType
<
typeof
getNewsPageConfigCategoryId
>>
,
TError
=
ErrorType
<
unknown
>>
(
id
:
string
,
options
?:
{
query
?:
Partial
<
UseQueryOptions
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfigCategoryId
>>
,
TError
,
TData
>>
,
request
?:
SecondParameter
<
typeof
useCustomClient
>
}
,
queryClient
?:
QueryClient
):
UseQueryResult
<
TData
,
TError
>
&
{
queryKey
:
DataTag
<
QueryKey
,
TData
,
TError
>
}
{
const
queryOptions
=
getGetNewsPageConfigCategoryIdQueryOptions
(
id
,
options
)
const
query
=
useQuery
(
queryOptions
,
queryClient
)
as
UseQueryResult
<
TData
,
TError
>
&
{
queryKey
:
DataTag
<
QueryKey
,
TData
,
TError
>
};
query
.
queryKey
=
queryOptions
.
queryKey
;
return
query
;
}
export
const
prefetchGetNewsPageConfigCategoryIdQuery
=
async
<
TData
=
Awaited
<
ReturnType
<
typeof
getNewsPageConfigCategoryId
>>
,
TError
=
ErrorType
<
unknown
>>
(
queryClient
:
QueryClient
,
id
:
string
,
options
?:
{
query
?:
Partial
<
UseQueryOptions
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfigCategoryId
>>
,
TError
,
TData
>>
,
request
?:
SecondParameter
<
typeof
useCustomClient
>
}
):
Promise
<
QueryClient
>
=>
{
const
queryOptions
=
getGetNewsPageConfigCategoryIdQueryOptions
(
id
,
options
)
await
queryClient
.
prefetchQuery
(
queryOptions
);
return
queryClient
;
}
/**
* Update page config category
*/
export
type
putNewsPageConfigCategoryIdResponse200
=
{
data
:
Response
status
:
200
}
export
type
putNewsPageConfigCategoryIdResponseSuccess
=
(
putNewsPageConfigCategoryIdResponse200
)
&
{
headers
:
Headers
;
};
;
export
type
putNewsPageConfigCategoryIdResponse
=
(
putNewsPageConfigCategoryIdResponseSuccess
)
export
const
getPutNewsPageConfigCategoryIdUrl
=
(
id
:
string
,)
=>
{
return
`/newsPageConfig/category/
${
id
}
`
}
export
const
putNewsPageConfigCategoryId
=
async
(
id
:
string
,
putNewsPageConfigCategoryIdBody
:
PutNewsPageConfigCategoryIdBody
,
options
?:
RequestInit
):
Promise
<
putNewsPageConfigCategoryIdResponse
>
=>
{
return
useCustomClient
<
putNewsPageConfigCategoryIdResponse
>
(
getPutNewsPageConfigCategoryIdUrl
(
id
),
{
...
options
,
method
:
'PUT'
,
headers
:
{
'Content-Type'
:
'application/json'
,
...
options
?.
headers
},
body
:
JSON
.
stringify
(
putNewsPageConfigCategoryIdBody
,)
}
);}
export
const
getPutNewsPageConfigCategoryIdMutationOptions
=
<
TError
=
ErrorType
<
unknown
>
,
TContext
=
unknown
>
(
options
?:
{
mutation
?:
UseMutationOptions
<
Awaited
<
ReturnType
<
typeof
putNewsPageConfigCategoryId
>>
,
TError
,{
id
:
string
;
data
:
BodyType
<
PutNewsPageConfigCategoryIdBody
>
},
TContext
>
,
request
?:
SecondParameter
<
typeof
useCustomClient
>
}
):
UseMutationOptions
<
Awaited
<
ReturnType
<
typeof
putNewsPageConfigCategoryId
>>
,
TError
,{
id
:
string
;
data
:
BodyType
<
PutNewsPageConfigCategoryIdBody
>
},
TContext
>
=>
{
const
mutationKey
=
[
'putNewsPageConfigCategoryId'
];
const
{
mutation
:
mutationOptions
,
request
:
requestOptions
}
=
options
?
options
.
mutation
&&
'mutationKey'
in
options
.
mutation
&&
options
.
mutation
.
mutationKey
?
options
:
{...
options
,
mutation
:
{...
options
.
mutation
,
mutationKey
}}
:
{
mutation
:
{
mutationKey
,
},
request
:
undefined
};
const
mutationFn
:
MutationFunction
<
Awaited
<
ReturnType
<
typeof
putNewsPageConfigCategoryId
>>
,
{
id
:
string
;
data
:
BodyType
<
PutNewsPageConfigCategoryIdBody
>
}
>
=
(
props
)
=>
{
const
{
id
,
data
}
=
props
??
{};
return
putNewsPageConfigCategoryId
(
id
,
data
,
requestOptions
)
}
return
{
mutationFn
,
...
mutationOptions
}}
export
type
PutNewsPageConfigCategoryIdMutationResult
=
NonNullable
<
Awaited
<
ReturnType
<
typeof
putNewsPageConfigCategoryId
>>>
export
type
PutNewsPageConfigCategoryIdMutationBody
=
BodyType
<
PutNewsPageConfigCategoryIdBody
>
export
type
PutNewsPageConfigCategoryIdMutationError
=
ErrorType
<
unknown
>
export
const
usePutNewsPageConfigCategoryId
=
<
TError
=
ErrorType
<
unknown
>
,
TContext
=
unknown
>
(
options
?:
{
mutation
?:
UseMutationOptions
<
Awaited
<
ReturnType
<
typeof
putNewsPageConfigCategoryId
>>
,
TError
,{
id
:
string
;
data
:
BodyType
<
PutNewsPageConfigCategoryIdBody
>
},
TContext
>
,
request
?:
SecondParameter
<
typeof
useCustomClient
>
}
,
queryClient
?:
QueryClient
):
UseMutationResult
<
Awaited
<
ReturnType
<
typeof
putNewsPageConfigCategoryId
>>
,
TError
,
{
id
:
string
;
data
:
BodyType
<
PutNewsPageConfigCategoryIdBody
>
},
TContext
>
=>
{
const
mutationOptions
=
getPutNewsPageConfigCategoryIdMutationOptions
(
options
);
return
useMutation
(
mutationOptions
,
queryClient
);
}
/**
* Get page config category
*/
export
type
getNewsPageConfigCategoryResponse200
=
{
data
:
Response
status
:
200
}
export
type
getNewsPageConfigCategoryResponseSuccess
=
(
getNewsPageConfigCategoryResponse200
)
&
{
headers
:
Headers
;
};
;
export
type
getNewsPageConfigCategoryResponse
=
(
getNewsPageConfigCategoryResponseSuccess
)
export
const
getGetNewsPageConfigCategoryUrl
=
()
=>
{
return
`/newsPageConfig/category`
}
export
const
getNewsPageConfigCategory
=
async
(
options
?:
RequestInit
):
Promise
<
getNewsPageConfigCategoryResponse
>
=>
{
return
useCustomClient
<
getNewsPageConfigCategoryResponse
>
(
getGetNewsPageConfigCategoryUrl
(),
{
...
options
,
method
:
'GET'
}
);}
export
const
getGetNewsPageConfigCategoryInfiniteQueryKey
=
()
=>
{
return
[
'infinite'
,
`/newsPageConfig/category`
]
as
const
;
}
export
const
getGetNewsPageConfigCategoryQueryKey
=
()
=>
{
return
[
`/newsPageConfig/category`
]
as
const
;
}
export
const
getGetNewsPageConfigCategoryInfiniteQueryOptions
=
<
TData
=
InfiniteData
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfigCategory
>>>
,
TError
=
ErrorType
<
unknown
>>
(
options
?:
{
query
?:
Partial
<
UseInfiniteQueryOptions
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfigCategory
>>
,
TError
,
TData
>>
,
request
?:
SecondParameter
<
typeof
useCustomClient
>
}
)
=>
{
const
{
query
:
queryOptions
,
request
:
requestOptions
}
=
options
??
{};
const
queryKey
=
queryOptions
?.
queryKey
??
getGetNewsPageConfigCategoryInfiniteQueryKey
();
const
queryFn
:
QueryFunction
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfigCategory
>>>
=
({
signal
})
=>
getNewsPageConfigCategory
({
signal
,
...
requestOptions
});
return
{
queryKey
,
queryFn
,
...
queryOptions
}
as
UseInfiniteQueryOptions
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfigCategory
>>
,
TError
,
TData
>
&
{
queryKey
:
DataTag
<
QueryKey
,
TData
,
TError
>
}
}
export
type
GetNewsPageConfigCategoryInfiniteQueryResult
=
NonNullable
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfigCategory
>>>
export
type
GetNewsPageConfigCategoryInfiniteQueryError
=
ErrorType
<
unknown
>
export
function
useGetNewsPageConfigCategoryInfinite
<
TData
=
InfiniteData
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfigCategory
>>>
,
TError
=
ErrorType
<
unknown
>>
(
options
:
{
query
:
Partial
<
UseInfiniteQueryOptions
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfigCategory
>>
,
TError
,
TData
>>
&
Pick
<
DefinedInitialDataOptions
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfigCategory
>>
,
TError
,
Awaited
<
ReturnType
<
typeof
getNewsPageConfigCategory
>>
>
,
'initialData'
>
,
request
?:
SecondParameter
<
typeof
useCustomClient
>
}
,
queryClient
?:
QueryClient
):
DefinedUseInfiniteQueryResult
<
TData
,
TError
>
&
{
queryKey
:
DataTag
<
QueryKey
,
TData
,
TError
>
}
export
function
useGetNewsPageConfigCategoryInfinite
<
TData
=
InfiniteData
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfigCategory
>>>
,
TError
=
ErrorType
<
unknown
>>
(
options
?:
{
query
?:
Partial
<
UseInfiniteQueryOptions
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfigCategory
>>
,
TError
,
TData
>>
&
Pick
<
UndefinedInitialDataOptions
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfigCategory
>>
,
TError
,
Awaited
<
ReturnType
<
typeof
getNewsPageConfigCategory
>>
>
,
'initialData'
>
,
request
?:
SecondParameter
<
typeof
useCustomClient
>
}
,
queryClient
?:
QueryClient
):
UseInfiniteQueryResult
<
TData
,
TError
>
&
{
queryKey
:
DataTag
<
QueryKey
,
TData
,
TError
>
}
export
function
useGetNewsPageConfigCategoryInfinite
<
TData
=
InfiniteData
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfigCategory
>>>
,
TError
=
ErrorType
<
unknown
>>
(
options
?:
{
query
?:
Partial
<
UseInfiniteQueryOptions
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfigCategory
>>
,
TError
,
TData
>>
,
request
?:
SecondParameter
<
typeof
useCustomClient
>
}
,
queryClient
?:
QueryClient
):
UseInfiniteQueryResult
<
TData
,
TError
>
&
{
queryKey
:
DataTag
<
QueryKey
,
TData
,
TError
>
}
export
function
useGetNewsPageConfigCategoryInfinite
<
TData
=
InfiniteData
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfigCategory
>>>
,
TError
=
ErrorType
<
unknown
>>
(
options
?:
{
query
?:
Partial
<
UseInfiniteQueryOptions
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfigCategory
>>
,
TError
,
TData
>>
,
request
?:
SecondParameter
<
typeof
useCustomClient
>
}
,
queryClient
?:
QueryClient
):
UseInfiniteQueryResult
<
TData
,
TError
>
&
{
queryKey
:
DataTag
<
QueryKey
,
TData
,
TError
>
}
{
const
queryOptions
=
getGetNewsPageConfigCategoryInfiniteQueryOptions
(
options
)
const
query
=
useInfiniteQuery
(
queryOptions
,
queryClient
)
as
UseInfiniteQueryResult
<
TData
,
TError
>
&
{
queryKey
:
DataTag
<
QueryKey
,
TData
,
TError
>
};
query
.
queryKey
=
queryOptions
.
queryKey
;
return
query
;
}
export
const
prefetchGetNewsPageConfigCategoryInfiniteQuery
=
async
<
TData
=
Awaited
<
ReturnType
<
typeof
getNewsPageConfigCategory
>>
,
TError
=
ErrorType
<
unknown
>>
(
queryClient
:
QueryClient
,
options
?:
{
query
?:
Partial
<
UseInfiniteQueryOptions
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfigCategory
>>
,
TError
,
TData
>>
,
request
?:
SecondParameter
<
typeof
useCustomClient
>
}
):
Promise
<
QueryClient
>
=>
{
const
queryOptions
=
getGetNewsPageConfigCategoryInfiniteQueryOptions
(
options
)
await
queryClient
.
prefetchInfiniteQuery
(
queryOptions
);
return
queryClient
;
}
export
const
getGetNewsPageConfigCategoryQueryOptions
=
<
TData
=
Awaited
<
ReturnType
<
typeof
getNewsPageConfigCategory
>>
,
TError
=
ErrorType
<
unknown
>>
(
options
?:
{
query
?:
Partial
<
UseQueryOptions
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfigCategory
>>
,
TError
,
TData
>>
,
request
?:
SecondParameter
<
typeof
useCustomClient
>
}
)
=>
{
const
{
query
:
queryOptions
,
request
:
requestOptions
}
=
options
??
{};
const
queryKey
=
queryOptions
?.
queryKey
??
getGetNewsPageConfigCategoryQueryKey
();
const
queryFn
:
QueryFunction
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfigCategory
>>>
=
({
signal
})
=>
getNewsPageConfigCategory
({
signal
,
...
requestOptions
});
return
{
queryKey
,
queryFn
,
...
queryOptions
}
as
UseQueryOptions
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfigCategory
>>
,
TError
,
TData
>
&
{
queryKey
:
DataTag
<
QueryKey
,
TData
,
TError
>
}
}
export
type
GetNewsPageConfigCategoryQueryResult
=
NonNullable
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfigCategory
>>>
export
type
GetNewsPageConfigCategoryQueryError
=
ErrorType
<
unknown
>
export
function
useGetNewsPageConfigCategory
<
TData
=
Awaited
<
ReturnType
<
typeof
getNewsPageConfigCategory
>>
,
TError
=
ErrorType
<
unknown
>>
(
options
:
{
query
:
Partial
<
UseQueryOptions
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfigCategory
>>
,
TError
,
TData
>>
&
Pick
<
DefinedInitialDataOptions
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfigCategory
>>
,
TError
,
Awaited
<
ReturnType
<
typeof
getNewsPageConfigCategory
>>
>
,
'initialData'
>
,
request
?:
SecondParameter
<
typeof
useCustomClient
>
}
,
queryClient
?:
QueryClient
):
DefinedUseQueryResult
<
TData
,
TError
>
&
{
queryKey
:
DataTag
<
QueryKey
,
TData
,
TError
>
}
export
function
useGetNewsPageConfigCategory
<
TData
=
Awaited
<
ReturnType
<
typeof
getNewsPageConfigCategory
>>
,
TError
=
ErrorType
<
unknown
>>
(
options
?:
{
query
?:
Partial
<
UseQueryOptions
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfigCategory
>>
,
TError
,
TData
>>
&
Pick
<
UndefinedInitialDataOptions
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfigCategory
>>
,
TError
,
Awaited
<
ReturnType
<
typeof
getNewsPageConfigCategory
>>
>
,
'initialData'
>
,
request
?:
SecondParameter
<
typeof
useCustomClient
>
}
,
queryClient
?:
QueryClient
):
UseQueryResult
<
TData
,
TError
>
&
{
queryKey
:
DataTag
<
QueryKey
,
TData
,
TError
>
}
export
function
useGetNewsPageConfigCategory
<
TData
=
Awaited
<
ReturnType
<
typeof
getNewsPageConfigCategory
>>
,
TError
=
ErrorType
<
unknown
>>
(
options
?:
{
query
?:
Partial
<
UseQueryOptions
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfigCategory
>>
,
TError
,
TData
>>
,
request
?:
SecondParameter
<
typeof
useCustomClient
>
}
,
queryClient
?:
QueryClient
):
UseQueryResult
<
TData
,
TError
>
&
{
queryKey
:
DataTag
<
QueryKey
,
TData
,
TError
>
}
export
function
useGetNewsPageConfigCategory
<
TData
=
Awaited
<
ReturnType
<
typeof
getNewsPageConfigCategory
>>
,
TError
=
ErrorType
<
unknown
>>
(
options
?:
{
query
?:
Partial
<
UseQueryOptions
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfigCategory
>>
,
TError
,
TData
>>
,
request
?:
SecondParameter
<
typeof
useCustomClient
>
}
,
queryClient
?:
QueryClient
):
UseQueryResult
<
TData
,
TError
>
&
{
queryKey
:
DataTag
<
QueryKey
,
TData
,
TError
>
}
{
const
queryOptions
=
getGetNewsPageConfigCategoryQueryOptions
(
options
)
const
query
=
useQuery
(
queryOptions
,
queryClient
)
as
UseQueryResult
<
TData
,
TError
>
&
{
queryKey
:
DataTag
<
QueryKey
,
TData
,
TError
>
};
query
.
queryKey
=
queryOptions
.
queryKey
;
return
query
;
}
export
const
prefetchGetNewsPageConfigCategoryQuery
=
async
<
TData
=
Awaited
<
ReturnType
<
typeof
getNewsPageConfigCategory
>>
,
TError
=
ErrorType
<
unknown
>>
(
queryClient
:
QueryClient
,
options
?:
{
query
?:
Partial
<
UseQueryOptions
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfigCategory
>>
,
TError
,
TData
>>
,
request
?:
SecondParameter
<
typeof
useCustomClient
>
}
):
Promise
<
QueryClient
>
=>
{
const
queryOptions
=
getGetNewsPageConfigCategoryQueryOptions
(
options
)
await
queryClient
.
prefetchQuery
(
queryOptions
);
return
queryClient
;
}
/**
* Get
*/
export
type
getNewsPageConfigGetAllLinksResponse200
=
{
data
:
Response
status
:
200
}
export
type
getNewsPageConfigGetAllLinksResponseSuccess
=
(
getNewsPageConfigGetAllLinksResponse200
)
&
{
headers
:
Headers
;
};
;
export
type
getNewsPageConfigGetAllLinksResponse
=
(
getNewsPageConfigGetAllLinksResponseSuccess
)
export
const
getGetNewsPageConfigGetAllLinksUrl
=
()
=>
{
return
`/newsPageConfig/getAllLinks`
}
export
const
getNewsPageConfigGetAllLinks
=
async
(
options
?:
RequestInit
):
Promise
<
getNewsPageConfigGetAllLinksResponse
>
=>
{
return
useCustomClient
<
getNewsPageConfigGetAllLinksResponse
>
(
getGetNewsPageConfigGetAllLinksUrl
(),
{
...
options
,
method
:
'GET'
}
);}
export
const
getGetNewsPageConfigGetAllLinksInfiniteQueryKey
=
()
=>
{
return
[
'infinite'
,
`/newsPageConfig/getAllLinks`
]
as
const
;
}
export
const
getGetNewsPageConfigGetAllLinksQueryKey
=
()
=>
{
return
[
`/newsPageConfig/getAllLinks`
]
as
const
;
}
export
const
getGetNewsPageConfigGetAllLinksInfiniteQueryOptions
=
<
TData
=
InfiniteData
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfigGetAllLinks
>>>
,
TError
=
ErrorType
<
unknown
>>
(
options
?:
{
query
?:
Partial
<
UseInfiniteQueryOptions
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfigGetAllLinks
>>
,
TError
,
TData
>>
,
request
?:
SecondParameter
<
typeof
useCustomClient
>
}
)
=>
{
const
{
query
:
queryOptions
,
request
:
requestOptions
}
=
options
??
{};
const
queryKey
=
queryOptions
?.
queryKey
??
getGetNewsPageConfigGetAllLinksInfiniteQueryKey
();
const
queryFn
:
QueryFunction
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfigGetAllLinks
>>>
=
({
signal
})
=>
getNewsPageConfigGetAllLinks
({
signal
,
...
requestOptions
});
return
{
queryKey
,
queryFn
,
...
queryOptions
}
as
UseInfiniteQueryOptions
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfigGetAllLinks
>>
,
TError
,
TData
>
&
{
queryKey
:
DataTag
<
QueryKey
,
TData
,
TError
>
}
}
export
type
GetNewsPageConfigGetAllLinksInfiniteQueryResult
=
NonNullable
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfigGetAllLinks
>>>
export
type
GetNewsPageConfigGetAllLinksInfiniteQueryError
=
ErrorType
<
unknown
>
export
function
useGetNewsPageConfigGetAllLinksInfinite
<
TData
=
InfiniteData
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfigGetAllLinks
>>>
,
TError
=
ErrorType
<
unknown
>>
(
options
:
{
query
:
Partial
<
UseInfiniteQueryOptions
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfigGetAllLinks
>>
,
TError
,
TData
>>
&
Pick
<
DefinedInitialDataOptions
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfigGetAllLinks
>>
,
TError
,
Awaited
<
ReturnType
<
typeof
getNewsPageConfigGetAllLinks
>>
>
,
'initialData'
>
,
request
?:
SecondParameter
<
typeof
useCustomClient
>
}
,
queryClient
?:
QueryClient
):
DefinedUseInfiniteQueryResult
<
TData
,
TError
>
&
{
queryKey
:
DataTag
<
QueryKey
,
TData
,
TError
>
}
export
function
useGetNewsPageConfigGetAllLinksInfinite
<
TData
=
InfiniteData
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfigGetAllLinks
>>>
,
TError
=
ErrorType
<
unknown
>>
(
options
?:
{
query
?:
Partial
<
UseInfiniteQueryOptions
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfigGetAllLinks
>>
,
TError
,
TData
>>
&
Pick
<
UndefinedInitialDataOptions
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfigGetAllLinks
>>
,
TError
,
Awaited
<
ReturnType
<
typeof
getNewsPageConfigGetAllLinks
>>
>
,
'initialData'
>
,
request
?:
SecondParameter
<
typeof
useCustomClient
>
}
,
queryClient
?:
QueryClient
):
UseInfiniteQueryResult
<
TData
,
TError
>
&
{
queryKey
:
DataTag
<
QueryKey
,
TData
,
TError
>
}
export
function
useGetNewsPageConfigGetAllLinksInfinite
<
TData
=
InfiniteData
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfigGetAllLinks
>>>
,
TError
=
ErrorType
<
unknown
>>
(
options
?:
{
query
?:
Partial
<
UseInfiniteQueryOptions
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfigGetAllLinks
>>
,
TError
,
TData
>>
,
request
?:
SecondParameter
<
typeof
useCustomClient
>
}
,
queryClient
?:
QueryClient
):
UseInfiniteQueryResult
<
TData
,
TError
>
&
{
queryKey
:
DataTag
<
QueryKey
,
TData
,
TError
>
}
export
function
useGetNewsPageConfigGetAllLinksInfinite
<
TData
=
InfiniteData
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfigGetAllLinks
>>>
,
TError
=
ErrorType
<
unknown
>>
(
options
?:
{
query
?:
Partial
<
UseInfiniteQueryOptions
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfigGetAllLinks
>>
,
TError
,
TData
>>
,
request
?:
SecondParameter
<
typeof
useCustomClient
>
}
,
queryClient
?:
QueryClient
):
UseInfiniteQueryResult
<
TData
,
TError
>
&
{
queryKey
:
DataTag
<
QueryKey
,
TData
,
TError
>
}
{
const
queryOptions
=
getGetNewsPageConfigGetAllLinksInfiniteQueryOptions
(
options
)
const
query
=
useInfiniteQuery
(
queryOptions
,
queryClient
)
as
UseInfiniteQueryResult
<
TData
,
TError
>
&
{
queryKey
:
DataTag
<
QueryKey
,
TData
,
TError
>
};
query
.
queryKey
=
queryOptions
.
queryKey
;
return
query
;
}
export
const
prefetchGetNewsPageConfigGetAllLinksInfiniteQuery
=
async
<
TData
=
Awaited
<
ReturnType
<
typeof
getNewsPageConfigGetAllLinks
>>
,
TError
=
ErrorType
<
unknown
>>
(
queryClient
:
QueryClient
,
options
?:
{
query
?:
Partial
<
UseInfiniteQueryOptions
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfigGetAllLinks
>>
,
TError
,
TData
>>
,
request
?:
SecondParameter
<
typeof
useCustomClient
>
}
):
Promise
<
QueryClient
>
=>
{
const
queryOptions
=
getGetNewsPageConfigGetAllLinksInfiniteQueryOptions
(
options
)
await
queryClient
.
prefetchInfiniteQuery
(
queryOptions
);
return
queryClient
;
}
export
const
getGetNewsPageConfigGetAllLinksQueryOptions
=
<
TData
=
Awaited
<
ReturnType
<
typeof
getNewsPageConfigGetAllLinks
>>
,
TError
=
ErrorType
<
unknown
>>
(
options
?:
{
query
?:
Partial
<
UseQueryOptions
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfigGetAllLinks
>>
,
TError
,
TData
>>
,
request
?:
SecondParameter
<
typeof
useCustomClient
>
}
)
=>
{
const
{
query
:
queryOptions
,
request
:
requestOptions
}
=
options
??
{};
const
queryKey
=
queryOptions
?.
queryKey
??
getGetNewsPageConfigGetAllLinksQueryKey
();
const
queryFn
:
QueryFunction
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfigGetAllLinks
>>>
=
({
signal
})
=>
getNewsPageConfigGetAllLinks
({
signal
,
...
requestOptions
});
return
{
queryKey
,
queryFn
,
...
queryOptions
}
as
UseQueryOptions
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfigGetAllLinks
>>
,
TError
,
TData
>
&
{
queryKey
:
DataTag
<
QueryKey
,
TData
,
TError
>
}
}
export
type
GetNewsPageConfigGetAllLinksQueryResult
=
NonNullable
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfigGetAllLinks
>>>
export
type
GetNewsPageConfigGetAllLinksQueryError
=
ErrorType
<
unknown
>
export
function
useGetNewsPageConfigGetAllLinks
<
TData
=
Awaited
<
ReturnType
<
typeof
getNewsPageConfigGetAllLinks
>>
,
TError
=
ErrorType
<
unknown
>>
(
options
:
{
query
:
Partial
<
UseQueryOptions
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfigGetAllLinks
>>
,
TError
,
TData
>>
&
Pick
<
DefinedInitialDataOptions
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfigGetAllLinks
>>
,
TError
,
Awaited
<
ReturnType
<
typeof
getNewsPageConfigGetAllLinks
>>
>
,
'initialData'
>
,
request
?:
SecondParameter
<
typeof
useCustomClient
>
}
,
queryClient
?:
QueryClient
):
DefinedUseQueryResult
<
TData
,
TError
>
&
{
queryKey
:
DataTag
<
QueryKey
,
TData
,
TError
>
}
export
function
useGetNewsPageConfigGetAllLinks
<
TData
=
Awaited
<
ReturnType
<
typeof
getNewsPageConfigGetAllLinks
>>
,
TError
=
ErrorType
<
unknown
>>
(
options
?:
{
query
?:
Partial
<
UseQueryOptions
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfigGetAllLinks
>>
,
TError
,
TData
>>
&
Pick
<
UndefinedInitialDataOptions
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfigGetAllLinks
>>
,
TError
,
Awaited
<
ReturnType
<
typeof
getNewsPageConfigGetAllLinks
>>
>
,
'initialData'
>
,
request
?:
SecondParameter
<
typeof
useCustomClient
>
}
,
queryClient
?:
QueryClient
):
UseQueryResult
<
TData
,
TError
>
&
{
queryKey
:
DataTag
<
QueryKey
,
TData
,
TError
>
}
export
function
useGetNewsPageConfigGetAllLinks
<
TData
=
Awaited
<
ReturnType
<
typeof
getNewsPageConfigGetAllLinks
>>
,
TError
=
ErrorType
<
unknown
>>
(
options
?:
{
query
?:
Partial
<
UseQueryOptions
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfigGetAllLinks
>>
,
TError
,
TData
>>
,
request
?:
SecondParameter
<
typeof
useCustomClient
>
}
,
queryClient
?:
QueryClient
):
UseQueryResult
<
TData
,
TError
>
&
{
queryKey
:
DataTag
<
QueryKey
,
TData
,
TError
>
}
export
function
useGetNewsPageConfigGetAllLinks
<
TData
=
Awaited
<
ReturnType
<
typeof
getNewsPageConfigGetAllLinks
>>
,
TError
=
ErrorType
<
unknown
>>
(
options
?:
{
query
?:
Partial
<
UseQueryOptions
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfigGetAllLinks
>>
,
TError
,
TData
>>
,
request
?:
SecondParameter
<
typeof
useCustomClient
>
}
,
queryClient
?:
QueryClient
):
UseQueryResult
<
TData
,
TError
>
&
{
queryKey
:
DataTag
<
QueryKey
,
TData
,
TError
>
}
{
const
queryOptions
=
getGetNewsPageConfigGetAllLinksQueryOptions
(
options
)
const
query
=
useQuery
(
queryOptions
,
queryClient
)
as
UseQueryResult
<
TData
,
TError
>
&
{
queryKey
:
DataTag
<
QueryKey
,
TData
,
TError
>
};
query
.
queryKey
=
queryOptions
.
queryKey
;
return
query
;
}
export
const
prefetchGetNewsPageConfigGetAllLinksQuery
=
async
<
TData
=
Awaited
<
ReturnType
<
typeof
getNewsPageConfigGetAllLinks
>>
,
TError
=
ErrorType
<
unknown
>>
(
queryClient
:
QueryClient
,
options
?:
{
query
?:
Partial
<
UseQueryOptions
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfigGetAllLinks
>>
,
TError
,
TData
>>
,
request
?:
SecondParameter
<
typeof
useCustomClient
>
}
):
Promise
<
QueryClient
>
=>
{
const
queryOptions
=
getGetNewsPageConfigGetAllLinksQueryOptions
(
options
)
await
queryClient
.
prefetchQuery
(
queryOptions
);
return
queryClient
;
}
/**
* Get
*/
export
type
getNewsPageConfigResponse200
=
{
data
:
Response
status
:
200
}
export
type
getNewsPageConfigResponseSuccess
=
(
getNewsPageConfigResponse200
)
&
{
headers
:
Headers
;
};
;
export
type
getNewsPageConfigResponse
=
(
getNewsPageConfigResponseSuccess
)
export
const
getGetNewsPageConfigUrl
=
()
=>
{
return
`/newsPageConfig`
}
export
const
getNewsPageConfig
=
async
(
options
?:
RequestInit
):
Promise
<
getNewsPageConfigResponse
>
=>
{
return
useCustomClient
<
getNewsPageConfigResponse
>
(
getGetNewsPageConfigUrl
(),
{
...
options
,
method
:
'GET'
}
);}
export
const
getGetNewsPageConfigInfiniteQueryKey
=
()
=>
{
return
[
'infinite'
,
`/newsPageConfig`
]
as
const
;
}
export
const
getGetNewsPageConfigQueryKey
=
()
=>
{
return
[
`/newsPageConfig`
]
as
const
;
}
export
const
getGetNewsPageConfigInfiniteQueryOptions
=
<
TData
=
InfiniteData
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfig
>>>
,
TError
=
ErrorType
<
unknown
>>
(
options
?:
{
query
?:
Partial
<
UseInfiniteQueryOptions
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfig
>>
,
TError
,
TData
>>
,
request
?:
SecondParameter
<
typeof
useCustomClient
>
}
)
=>
{
const
{
query
:
queryOptions
,
request
:
requestOptions
}
=
options
??
{};
const
queryKey
=
queryOptions
?.
queryKey
??
getGetNewsPageConfigInfiniteQueryKey
();
const
queryFn
:
QueryFunction
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfig
>>>
=
({
signal
})
=>
getNewsPageConfig
({
signal
,
...
requestOptions
});
return
{
queryKey
,
queryFn
,
...
queryOptions
}
as
UseInfiniteQueryOptions
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfig
>>
,
TError
,
TData
>
&
{
queryKey
:
DataTag
<
QueryKey
,
TData
,
TError
>
}
}
export
type
GetNewsPageConfigInfiniteQueryResult
=
NonNullable
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfig
>>>
export
type
GetNewsPageConfigInfiniteQueryError
=
ErrorType
<
unknown
>
export
function
useGetNewsPageConfigInfinite
<
TData
=
InfiniteData
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfig
>>>
,
TError
=
ErrorType
<
unknown
>>
(
options
:
{
query
:
Partial
<
UseInfiniteQueryOptions
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfig
>>
,
TError
,
TData
>>
&
Pick
<
DefinedInitialDataOptions
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfig
>>
,
TError
,
Awaited
<
ReturnType
<
typeof
getNewsPageConfig
>>
>
,
'initialData'
>
,
request
?:
SecondParameter
<
typeof
useCustomClient
>
}
,
queryClient
?:
QueryClient
):
DefinedUseInfiniteQueryResult
<
TData
,
TError
>
&
{
queryKey
:
DataTag
<
QueryKey
,
TData
,
TError
>
}
export
function
useGetNewsPageConfigInfinite
<
TData
=
InfiniteData
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfig
>>>
,
TError
=
ErrorType
<
unknown
>>
(
options
?:
{
query
?:
Partial
<
UseInfiniteQueryOptions
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfig
>>
,
TError
,
TData
>>
&
Pick
<
UndefinedInitialDataOptions
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfig
>>
,
TError
,
Awaited
<
ReturnType
<
typeof
getNewsPageConfig
>>
>
,
'initialData'
>
,
request
?:
SecondParameter
<
typeof
useCustomClient
>
}
,
queryClient
?:
QueryClient
):
UseInfiniteQueryResult
<
TData
,
TError
>
&
{
queryKey
:
DataTag
<
QueryKey
,
TData
,
TError
>
}
export
function
useGetNewsPageConfigInfinite
<
TData
=
InfiniteData
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfig
>>>
,
TError
=
ErrorType
<
unknown
>>
(
options
?:
{
query
?:
Partial
<
UseInfiniteQueryOptions
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfig
>>
,
TError
,
TData
>>
,
request
?:
SecondParameter
<
typeof
useCustomClient
>
}
,
queryClient
?:
QueryClient
):
UseInfiniteQueryResult
<
TData
,
TError
>
&
{
queryKey
:
DataTag
<
QueryKey
,
TData
,
TError
>
}
export
function
useGetNewsPageConfigInfinite
<
TData
=
InfiniteData
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfig
>>>
,
TError
=
ErrorType
<
unknown
>>
(
options
?:
{
query
?:
Partial
<
UseInfiniteQueryOptions
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfig
>>
,
TError
,
TData
>>
,
request
?:
SecondParameter
<
typeof
useCustomClient
>
}
,
queryClient
?:
QueryClient
):
UseInfiniteQueryResult
<
TData
,
TError
>
&
{
queryKey
:
DataTag
<
QueryKey
,
TData
,
TError
>
}
{
const
queryOptions
=
getGetNewsPageConfigInfiniteQueryOptions
(
options
)
const
query
=
useInfiniteQuery
(
queryOptions
,
queryClient
)
as
UseInfiniteQueryResult
<
TData
,
TError
>
&
{
queryKey
:
DataTag
<
QueryKey
,
TData
,
TError
>
};
query
.
queryKey
=
queryOptions
.
queryKey
;
return
query
;
}
export
const
prefetchGetNewsPageConfigInfiniteQuery
=
async
<
TData
=
Awaited
<
ReturnType
<
typeof
getNewsPageConfig
>>
,
TError
=
ErrorType
<
unknown
>>
(
queryClient
:
QueryClient
,
options
?:
{
query
?:
Partial
<
UseInfiniteQueryOptions
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfig
>>
,
TError
,
TData
>>
,
request
?:
SecondParameter
<
typeof
useCustomClient
>
}
):
Promise
<
QueryClient
>
=>
{
const
queryOptions
=
getGetNewsPageConfigInfiniteQueryOptions
(
options
)
await
queryClient
.
prefetchInfiniteQuery
(
queryOptions
);
return
queryClient
;
}
export
const
getGetNewsPageConfigQueryOptions
=
<
TData
=
Awaited
<
ReturnType
<
typeof
getNewsPageConfig
>>
,
TError
=
ErrorType
<
unknown
>>
(
options
?:
{
query
?:
Partial
<
UseQueryOptions
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfig
>>
,
TError
,
TData
>>
,
request
?:
SecondParameter
<
typeof
useCustomClient
>
}
)
=>
{
const
{
query
:
queryOptions
,
request
:
requestOptions
}
=
options
??
{};
const
queryKey
=
queryOptions
?.
queryKey
??
getGetNewsPageConfigQueryKey
();
const
queryFn
:
QueryFunction
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfig
>>>
=
({
signal
})
=>
getNewsPageConfig
({
signal
,
...
requestOptions
});
return
{
queryKey
,
queryFn
,
...
queryOptions
}
as
UseQueryOptions
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfig
>>
,
TError
,
TData
>
&
{
queryKey
:
DataTag
<
QueryKey
,
TData
,
TError
>
}
}
export
type
GetNewsPageConfigQueryResult
=
NonNullable
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfig
>>>
export
type
GetNewsPageConfigQueryError
=
ErrorType
<
unknown
>
export
function
useGetNewsPageConfig
<
TData
=
Awaited
<
ReturnType
<
typeof
getNewsPageConfig
>>
,
TError
=
ErrorType
<
unknown
>>
(
options
:
{
query
:
Partial
<
UseQueryOptions
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfig
>>
,
TError
,
TData
>>
&
Pick
<
DefinedInitialDataOptions
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfig
>>
,
TError
,
Awaited
<
ReturnType
<
typeof
getNewsPageConfig
>>
>
,
'initialData'
>
,
request
?:
SecondParameter
<
typeof
useCustomClient
>
}
,
queryClient
?:
QueryClient
):
DefinedUseQueryResult
<
TData
,
TError
>
&
{
queryKey
:
DataTag
<
QueryKey
,
TData
,
TError
>
}
export
function
useGetNewsPageConfig
<
TData
=
Awaited
<
ReturnType
<
typeof
getNewsPageConfig
>>
,
TError
=
ErrorType
<
unknown
>>
(
options
?:
{
query
?:
Partial
<
UseQueryOptions
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfig
>>
,
TError
,
TData
>>
&
Pick
<
UndefinedInitialDataOptions
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfig
>>
,
TError
,
Awaited
<
ReturnType
<
typeof
getNewsPageConfig
>>
>
,
'initialData'
>
,
request
?:
SecondParameter
<
typeof
useCustomClient
>
}
,
queryClient
?:
QueryClient
):
UseQueryResult
<
TData
,
TError
>
&
{
queryKey
:
DataTag
<
QueryKey
,
TData
,
TError
>
}
export
function
useGetNewsPageConfig
<
TData
=
Awaited
<
ReturnType
<
typeof
getNewsPageConfig
>>
,
TError
=
ErrorType
<
unknown
>>
(
options
?:
{
query
?:
Partial
<
UseQueryOptions
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfig
>>
,
TError
,
TData
>>
,
request
?:
SecondParameter
<
typeof
useCustomClient
>
}
,
queryClient
?:
QueryClient
):
UseQueryResult
<
TData
,
TError
>
&
{
queryKey
:
DataTag
<
QueryKey
,
TData
,
TError
>
}
export
function
useGetNewsPageConfig
<
TData
=
Awaited
<
ReturnType
<
typeof
getNewsPageConfig
>>
,
TError
=
ErrorType
<
unknown
>>
(
options
?:
{
query
?:
Partial
<
UseQueryOptions
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfig
>>
,
TError
,
TData
>>
,
request
?:
SecondParameter
<
typeof
useCustomClient
>
}
,
queryClient
?:
QueryClient
):
UseQueryResult
<
TData
,
TError
>
&
{
queryKey
:
DataTag
<
QueryKey
,
TData
,
TError
>
}
{
const
queryOptions
=
getGetNewsPageConfigQueryOptions
(
options
)
const
query
=
useQuery
(
queryOptions
,
queryClient
)
as
UseQueryResult
<
TData
,
TError
>
&
{
queryKey
:
DataTag
<
QueryKey
,
TData
,
TError
>
};
query
.
queryKey
=
queryOptions
.
queryKey
;
return
query
;
}
export
const
prefetchGetNewsPageConfigQuery
=
async
<
TData
=
Awaited
<
ReturnType
<
typeof
getNewsPageConfig
>>
,
TError
=
ErrorType
<
unknown
>>
(
queryClient
:
QueryClient
,
options
?:
{
query
?:
Partial
<
UseQueryOptions
<
Awaited
<
ReturnType
<
typeof
getNewsPageConfig
>>
,
TError
,
TData
>>
,
request
?:
SecondParameter
<
typeof
useCustomClient
>
}
):
Promise
<
QueryClient
>
=>
{
const
queryOptions
=
getGetNewsPageConfigQueryOptions
(
options
)
await
queryClient
.
prefetchQuery
(
queryOptions
);
return
queryClient
;
}
src/api/models/index.ts
View file @
5ca290c8
...
...
@@ -140,6 +140,7 @@ export * from './putEventsLinkParams';
export
*
from
'./putEventsParams'
;
export
*
from
'./putFooterParams'
;
export
*
from
'./putMembershipFeeParams'
;
export
*
from
'./putNewsPageConfigCategoryIdBody'
;
export
*
from
'./putNotificationsMarkAsReadParams'
;
export
*
from
'./putNotificationsParams'
;
export
*
from
'./putOrderPaymentParams'
;
...
...
src/api/models/putNewsPageConfigCategoryIdBody.ts
0 → 100644
View file @
5ca290c8
/**
* Generated by orval v8.0.0-rc.0 🍺
* Do not edit manually.
* VCCI
* Coded by Meu TEAM
* OpenAPI spec version: 1.0.0
*/
export
type
PutNewsPageConfigCategoryIdBody
=
{
category_ids
?:
string
[];
};
src/api/types/event.ts
View file @
5ca290c8
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)/(home)/[id]/page.tsx
View file @
5ca290c8
...
...
@@ -41,7 +41,7 @@ const NewsDetailPage = () => {
<
div
className=
"grid grid-cols-1 lg:grid-cols-3 gap-5"
>
{
/* Main content */
}
<
main
className=
"lg:col-span-2 bg-white border rounded-md p-7"
>
<
div
className=
'pb-5 text-
blue-900
text-2xl leading-normal font-medium'
>
<
div
className=
'pb-5 text-
primary
text-2xl leading-normal font-medium'
>
{
data
?.
responseData
?.
title
}
</
div
>
<
div
className=
'flex items-center gap-2 text-sm mb-4'
>
...
...
src/app/(main)/(home)/components/card-event/index.tsx
View file @
5ca290c8
...
...
@@ -13,6 +13,10 @@ function CardEvent({ event }: { event: EventItem }) {
src=
{
`${BASE_URL.imageEndpoint}${event.image}`
}
alt=
{
event
.
name
}
className=
'w-[100px] md:w-[130px] aspect-3/2 object-cover'
onError=
{
(
e
)
=>
{
e
.
currentTarget
.
onerror
=
null
e
.
currentTarget
.
src
=
"/fallback.png"
}
}
/>
<
div
className=
'flex-1'
>
<
p
className=
'text-[#0056b3] font-bold text-sm line-clamp-2'
>
...
...
src/app/(main)/(home)/components/card-news/index.tsx
View file @
5ca290c8
...
...
@@ -12,8 +12,13 @@ function CardNews({ news }: { news: NewsAdminItem }) {
<
img
src=
{
`${BASE_URL.imageEndpoint}${news.thumbnail}`
}
alt=
{
news
.
title
}
className=
'w-[100px] md:w-[130px] aspect-3/2 object-cover'
className=
"w-[100px] md:w-[130px] aspect-3/2 object-cover"
onError=
{
(
e
)
=>
{
e
.
currentTarget
.
onerror
=
null
e
.
currentTarget
.
src
=
"/fallback.png"
}
}
/>
<
div
className=
'flex-1'
>
<
p
className=
'text-[#0056b3] font-bold text-sm line-clamp-2'
>
{
news
.
title
}
...
...
src/app/(main)/(home)/page.tsx
View file @
5ca290c8
...
...
@@ -30,7 +30,9 @@ const Page = () => {
const
swiperRef
=
useRef
<
SwiperType
|
null
>
(
null
)
const
{
data
:
categoryData
,
isLoading
:
isLoadingCategory
}
=
useGetCategory
<
GetCategoryAdminResponseType
>
()
const
{
data
:
newsData
,
isLoading
:
isLoadingNews
}
=
useGetNews
<
GetNewsAdminResponseType
>
()
const
{
data
:
newsData
,
isLoading
:
isLoadingNews
}
=
useGetNews
<
GetNewsAdminResponseType
>
(
{
pageSize
:
'999'
},
)
const
{
data
:
eventData
,
isLoading
:
isLoadingEvent
}
=
useGetEvents
<
EventApiResponse
>
()
// filter category
...
...
@@ -178,6 +180,10 @@ const Page = () => {
src=
{
`${BASE_URL.imageEndpoint}${news.thumbnail}`
}
alt=
{
news
.
title
}
className=
"w-full h-full object-cover"
onError=
{
(
e
)
=>
{
e
.
currentTarget
.
onerror
=
null
e
.
currentTarget
.
src
=
"/fallback.png"
}
}
/>
</
div
>
...
...
@@ -281,7 +287,10 @@ const Page = () => {
src=
{
`${BASE_URL.imageEndpoint}${event.image}`
}
alt=
{
event
.
name
}
className=
"w-full h-full object-cover"
/>
onError=
{
(
e
)
=>
{
e
.
currentTarget
.
onerror
=
null
e
.
currentTarget
.
src
=
"/fallback.png"
}
}
/>
</
div
>
<
div
className=
"flex-1"
>
...
...
src/app/(main)/_lib/layout/footer.tsx
View file @
5ca290c8
...
...
@@ -14,7 +14,7 @@ import {
import
Image
from
"next/image"
;
import
vietnamMap
from
"@/assets/vietnam-map-white.png.webp"
;
function
f
ooter
()
{
function
F
ooter
()
{
const
emailRef
=
useRef
<
HTMLInputElement
>
(
null
);
const
checkBoxRef
=
useRef
<
HTMLInputElement
>
(
null
);
const
[
emailError
,
setEmailError
]
=
useState
(
false
);
...
...
@@ -212,4 +212,4 @@ function footer() {
);
}
export
default
f
ooter
;
export
default
F
ooter
;
src/app/(main)/_lib/layout/header.tsx
View file @
5ca290c8
"use client"
;
import
React
,
{
useState
}
from
"react"
;
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"
;
import
MenuItem
from
"./MenuItem"
;
import
Link
from
"next/link"
;
function
Header
()
{
const
[
toggleMenu
,
setToggleMenu
]
=
useState
<
boolean
>
(
false
);
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
"
>
s
itemap
</
a
>
<
a
S
itemap
</
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"
>
...
...
@@ -41,6 +42,14 @@ function Header() {
className=
"bg-white h-12 rounded-sm outline-none px-4 w-64 placeholder:text-sm"
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}`
);
}
}
}
/>
<
div
className=
"flex gap-2"
>
{
[
Facebook
,
Twitter
,
Youtube
,
Linkedin
].
map
((
Icon
,
i
)
=>
(
...
...
@@ -57,17 +66,17 @@ function Header() {
</
div
>
</
div
>
<
div
className=
"sticky top-0 z-50 bg-[#ededed] shadow-md"
>
<
div
className=
"sticky top-0 z-50 bg-[#ededed] shadow-md
py-4
"
>
<
div
className=
"container m-auto"
>
<
div
className=
"w-full flex justify-between items-center"
>
{
/* Logo */
}
<
a
href=
"/"
className=
"flex items-center
"
>
<
Link
href=
"/
"
>
<
Image
className=
"w-[140px] object-contain
lg:ml-0 ml-10
"
className=
"w-[140px] object-contain"
src=
{
logo
}
alt=
"VCCI HCM"
/>
</
a
>
</
Link
>
{
/* Desktop Menu */
}
<
nav
className=
"hidden lg:flex items-center"
>
...
...
@@ -112,7 +121,7 @@ function Header() {
items=
{
[
{
title
:
"Định Nghĩa Chung"
,
link
:
"
dinh-nghia-chung
"
,
link
:
""
,
},
{
title
:
"Mục Đích Của C/O"
,
...
...
src/app/(main)/dai-dien-gioi-chu/chu-de/[id]/page.tsx
View file @
5ca290c8
...
...
@@ -20,6 +20,10 @@ 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
}
</
div
>
<
hr
className=
"py-2"
/>
<
div
className=
"p-7.5 prose tiptap overflow-hidden"
>
{
parse
(
data
?.
responseData
?.
description
??
''
)
}
</
div
>
</
main
>
...
...
src/app/(main)/dai-dien-gioi-chu/chu-de/page.tsx
View file @
5ca290c8
...
...
@@ -9,15 +9,17 @@ 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
,
// filters: submitSearch ? `title @=${submitSearch}` : undefined,
filters
:
'category@=Chủ đề'
});
return
(
<
div
className=
"min-h-screen container mx-auto p-4"
>
...
...
@@ -28,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 @
5ca290c8
...
...
@@ -2,8 +2,24 @@
import
{
NewsItem
}
from
'@app/dai-dien-gioi-chu/lib/types/NewsPage.type'
;
import
Links
from
'@links/index'
import
dayjs
from
'dayjs'
;
import
parse
from
'html-react-parser'
function
NewsContent
({
news
,
link
}:
{
news
:
NewsItem
,
link
:
string
})
{
import
{
EventItem
}
from
"@api/types/event"
;
// Helper: remove <img> tags and extract plain text from HTML
const
stripImagesAndHtml
=
(
html
?:
string
)
=>
{
if
(
!
html
)
return
''
// remove img tags first
const
withoutImgs
=
html
.
replace
(
/<img
[^
>
]
*>/gi
,
''
)
// use DOMParser on client for robust extraction
if
(
typeof
window
!==
'undefined'
&&
typeof
DOMParser
!==
'undefined'
)
{
try
{
const
doc
=
new
DOMParser
().
parseFromString
(
withoutImgs
,
'text/html'
)
return
doc
.
body
.
textContent
||
''
}
catch
{
// fallback to regex
}
}
return
withoutImgs
.
replace
(
/<
[^
>
]
*>/g
,
''
)
}
function
NewsContent
({
news
,
link
,
event
}:
{
news
?:
NewsItem
,
link
:
string
,
event
?:
EventItem
})
{
return
(
<
a
...
...
@@ -11,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"
...
...
@@ -21,14 +37,14 @@ 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 hover:no-underline
"
>
{
news
.
titl
e
}
<
p
className=
"text-primary font-semibold text-base md:text-lg hover:underline line-clamp-2 wrap-break-word
"
>
{
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"
>
{
parse
(
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/lib/sampleHtml.ts
View file @
5ca290c8
export
const
SAMPLE_HTML
=
`
<div class="document">
<h1
style="font-size:18px; font-weight:700; margin-bottom:8
px;">Chức năng Đại diện Người sử dụng lao động</h1>
<h1
class="text-primary" style="font-size:20px; font-weight:700; margin-bottom:12
px;">Chức năng Đại diện Người sử dụng lao động</h1>
<p>Chức năng Đại diện Người sử dụng lao động (NSDLĐ):</p>
...
...
src/app/(main)/dai-dien-gioi-chu/tap-huan-nsdld/[id]/page.tsx
View file @
5ca290c8
...
...
@@ -20,6 +20,10 @@ 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
}
</
div
>
<
hr
className=
"py-2"
/>
<
div
className=
"p-7.5 prose tiptap overflow-hidden"
>
{
parse
(
data
?.
responseData
?.
description
??
''
)
}
</
div
>
</
main
>
...
...
src/app/(main)/dai-dien-gioi-chu/tap-huan-nsdld/page.tsx
View file @
5ca290c8
...
...
@@ -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/[id]/page.tsx
View file @
5ca290c8
...
...
@@ -4,23 +4,31 @@ import Image from "next/image";
import
ListCategory
from
"../../components/list-category"
;
import
{
OWNER_REPRESENTATIVES_CATEGORIES
}
from
"@constants/categories"
;
import
ListFilter
from
"../../components/list-filter"
;
import
{
useGetNewsId
}
from
'@/api/endpoints/news'
;
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
{
useParams
}
from
"next/navigation"
;
import
{
GetNewsDetailResponseType
}
from
"@lib/types/news-detail-response-data"
;
// ...existing code...
const
Page
:
React
.
FC
=
()
=>
{
const
{
id
}
=
useParams
()
const
{
data
,
isLoading
}
=
useGetNewsId
<
GetNewsDetailResponseType
>
(
id
as
string
)
const
{
id
}
=
useParams
();
const
{
data
,
isLoading
}
=
useGetNewsId
<
GetNewsDetailResponseType
>
(
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"
>
<
ListCategory
categories=
{
OWNER_REPRESENTATIVES_CATEGORIES
}
/>
<
ListCategory
categories=
{
OWNER_REPRESENTATIVES_CATEGORIES
}
/>
<
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=
"p-7.5 prose tiptap overflow-hidden"
>
{
parse
(
data
?.
responseData
?.
description
??
''
)
}
</
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
>
</
main
>
{
/* Sidebar */
}
...
...
src/app/(main)/dai-dien-gioi-chu/tin-lien-quan/page.tsx
View file @
5ca290c8
...
...
@@ -9,14 +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
[
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
,
filters
:
submitSearch
?
`title @=
${
submitSearch
}
,category@=Tin liên quan`
:
'category@=Tin liên quan'
,
});
return
(
<
div
className=
"min-h-screen container mx-auto p-4"
>
...
...
@@ -27,25 +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
.
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
>
{
/* Sidebar */
}
<
aside
className=
"space-y-6 order-first lg:order-last"
>
<
ListFilter
/>
<
ListFilter
onSearch=
{
setsubmitSearch
}
/>
<
div
className=
"bg-white border rounded-md overflow-hidden hidden lg:block"
>
<
div
className=
"w-full h-56 relative bg-gray-100"
>
...
...
src/app/(main)/hoat-dong/dao-tao/[id]/page.tsx
View file @
5ca290c8
...
...
@@ -20,6 +20,10 @@ 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
}
</
div
>
<
hr
className=
"py-2"
/>
<
div
className=
"p-7.5 prose tiptap overflow-hidden"
>
{
parse
(
data
?.
responseData
?.
description
??
''
)
}
</
div
>
</
main
>
...
...
src/app/(main)/hoat-dong/dao-tao/page.tsx
View file @
5ca290c8
...
...
@@ -4,43 +4,53 @@ import ListCategory from "@app/dai-dien-gioi-chu/components/list-category";
import
{
EVENT_CATEGORIES
}
from
"@constants/categories"
;
import
EventFilter
from
"@app/dai-dien-gioi-chu/components/event-filter"
;
import
NewsContent
from
"@app/dai-dien-gioi-chu/components/card-news"
;
import
{
Pagination
}
from
"@components/base/pagination"
;
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
{
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
,
filters
:
submitSearch
?
`title @=
${
submitSearch
}
`
:
'category @=Đào tạo'
,
});
return
(
<
div
className=
"min-h-screen container mx-auto p-4"
>
<
div
className=
"w-full flex flex-col gap-5"
>
<
ListCategory
categories=
{
EVENT_CATEGORIES
}
/>
<
ListCategory
categories=
{
EVENT_CATEGORIES
}
/>
<
div
className=
"grid grid-cols-1 lg:grid-cols-3 gap-6"
>
{
/* 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/page.tsx
View file @
5ca290c8
...
...
@@ -15,7 +15,7 @@ export default function Page() {
return
(
<
div
className=
"min-h-screen container mx-auto p-4"
>
<
div
className=
"w-full flex flex-col gap-5"
>
<
ListCategory
categories=
{
EVENT_CATEGORIES
}
/>
<
ListCategory
categories=
{
EVENT_CATEGORIES
}
/>
</
div
>
</
div
>
);
...
...
src/app/(main)/hoat-dong/su-kien/[id]/page.tsx
View file @
5ca290c8
...
...
@@ -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,7 +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=
"p-7.5 prose tiptap overflow-hidden"
>
{
parse
(
data
?.
responseData
?.
description
??
''
)
}
</
div
>
{
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
>
</>
)
}
</
main
>
{
/* Sidebar */
}
...
...
src/app/(main)/hoat-dong/su-kien/page.tsx
View file @
5ca290c8
...
...
@@ -5,43 +5,57 @@ import { EVENT_CATEGORIES } from "@constants/categories";
import
EventFilter
from
"@app/dai-dien-gioi-chu/components/event-filter"
;
import
NewsContent
from
"@app/dai-dien-gioi-chu/components/card-news"
;
// ...existing code...
import
{
Pagination
}
from
"@components/base/pagination"
;
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
}
`
:
undefined
,
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"
>
<
div
className=
"w-full flex flex-col gap-5"
>
<
ListCategory
categories=
{
EVENT_CATEGORIES
}
/>
<
ListCategory
categories=
{
EVENT_CATEGORIES
}
/>
<
div
className=
"grid grid-cols-1 lg:grid-cols-3 gap-6"
>
{
/* 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 @
5ca290c8
...
...
@@ -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
(
""
);
...
...
@@ -16,7 +17,7 @@ export default function Page() {
const
{
data
:
allData
,
isLoading
}
=
useGetNews
<
GetNewsResponseType
>
({
pageSize
:
String
(
pageSize
),
currentPage
:
String
(
page
),
filters
:
submitSearch
?
`title @=
${
submitSearch
}
`
:
undefined
,
filters
:
submitSearch
?
`title @=
${
submitSearch
}
`
:
`category @=Kết nối hội viên`
,
});
return
(
<
div
className=
"min-h-screen container mx-auto pb-4"
>
...
...
@@ -26,28 +27,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
)
=>
(
<
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
>
</
main
>
<
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
>
{
/* Sidebar */
}
<
aside
className=
"space-y-6"
>
...
...
src/app/(main)/hoi-vien/tin-hoi-vien/page.tsx
View file @
5ca290c8
...
...
@@ -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
(
''
)
...
...
@@ -16,7 +17,7 @@ export default function Page() {
const
{
data
:
allData
,
isLoading
}
=
useGetNews
<
GetNewsResponseType
>
({
pageSize
:
String
(
pageSize
),
currentPage
:
String
(
page
),
filters
:
submitSearch
?
`title @=
${
submitSearch
}
`
:
undefined
,
filters
:
submitSearch
?
`title @=
${
submitSearch
}
`
:
'category @=Tin hội viên'
,
})
return
(
<
div
className=
"min-h-screen container mx-auto pb-4"
>
...
...
@@ -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
0 → 100644
View file @
5ca290c8
"use client"
;
import
React
,
{
useState
,
Suspense
}
from
"react"
;
import
ListCategory
from
"@app/dai-dien-gioi-chu/components/list-category"
;
import
{
OWNER_REPRESENTATIVES_CATEGORIES
}
from
"@constants/categories"
;
import
ListFilter
from
"@app/dai-dien-gioi-chu/components/list-filter"
;
import
NewsContent
from
"@app/dai-dien-gioi-chu/components/card-news"
;
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'
function
SearchContent
()
{
const
[
page
,
setPage
]
=
useState
(
1
);
const
searchParams
=
useSearchParams
()
const
query
=
searchParams
.
get
(
'q'
)
//
const
pageSize
=
5
;
const
{
data
:
allData
,
isLoading
}
=
useGetNews
<
GetNewsResponseType
>
({
pageSize
:
String
(
pageSize
),
currentPage
:
String
(
page
),
filters
:
query
?
`title @=
${
query
}
`
:
undefined
,
});
return
(
<
div
className=
"min-h-screen container mx-auto p-4"
>
<
div
className=
"w-full flex flex-col gap-5"
>
<
div
className=
"border-t border-gray-200 bg-white p-2.5"
>
<
div
className=
"w-full px-4 sm:px-6 lg:px-8"
>
<
div
className=
"py-3"
>
<
h1
className=
"text-md md:text-lg font-semibold leading-6 text-gray-900"
>
{
" "
}
Search Results for:
{
query
}
</
h1
>
</
div
>
</
div
>
</
div
>
<
div
className=
"grid grid-cols-1 lg:grid-cols-3 gap-6"
>
{
/* Main content */
}
<
main
className=
"lg:col-span-2 bg-background "
>
<
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
)
=>
(
<
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
>
</
main
>
{
/* Sidebar */
}
<
aside
className=
"space-y-6 order-first lg:order-last"
>
<
div
className=
"bg-white border rounded-md overflow-hidden hidden lg:block"
>
<
div
className=
"w-full h-62 relative bg-gray-100"
>
<
Image
src=
"/banner.webp"
alt=
"Quảng cáo"
fill
className=
"object-cover"
/>
</
div
>
</
div
>
</
aside
>
</
div
>
</
div
>
</
div
>
);
}
export
default
function
Page
()
{
return
(
<
Suspense
fallback=
{
<
div
className=
"min-h-screen container mx-auto p-4 flex items-center justify-center"
>
<
div
className=
"text-center"
>
<
div
className=
"animate-spin rounded-full h-12 w-12 border-b-2 border-[#063e8e] mx-auto"
></
div
>
<
p
className=
"mt-4 text-gray-600"
>
Loading search results...
</
p
>
</
div
>
</
div
>
}
>
<
SearchContent
/>
</
Suspense
>
);
}
src/app/(main)/site-map/_lib/mock-data.ts
0 → 100644
View file @
5ca290c8
export
type
SiteMapItem
=
{
label
:
string
;
url
:
string
;
children
?:
SiteMapItem
[];
};
export
const
MOCK_SITEMAP
:
SiteMapItem
[]
=
[
{
label
:
"Trang chủ"
,
url
:
"/homepage"
,
children
:
[]
},
{
label
:
"Giới thiệu"
,
url
:
"/gioi-thieu"
,
children
:
[
{
label
:
"Về VCCI-HCM"
,
url
:
"/gioi-thieu/ve-vcci-hcm"
,
children
:
[]
},
{
label
:
"Chức năng và nhiệm vụ"
,
url
:
"/gioi-thieu/chuc-nang-nhiem-vu"
,
children
:
[]
},
{
label
:
"Sơ đồ tổ chức"
,
url
:
"/gioi-thieu/so-do-to-chuc"
,
children
:
[]
},
{
label
:
"Dịch vụ cung cấp"
,
url
:
"/gioi-thieu/dich-vu-cung-cap"
,
children
:
[]
},
],
},
{
label
:
"Hội viên"
,
url
:
"/hoi-vien"
,
children
:
[
{
label
:
"Lợi ích của hội viên VCCI"
,
url
:
"/hoi-vien/loi-ich-hoi-vien"
,
children
:
[]
},
{
label
:
"Đăng ký hội viên"
,
url
:
"/hoi-vien/dang-ky-hoi-vien"
,
children
:
[]
},
{
label
:
"Kết nối hội viên"
,
url
:
"/hoi-vien/ket-noi-hoi-vien"
,
children
:
[]
},
{
label
:
"Tin hội viên"
,
url
:
"/hoi-vien/tin-hoi-vien"
,
children
:
[]
},
],
},
{
label
:
"Hoạt động"
,
url
:
"/hoat-dong"
,
children
:
[
{
label
:
"Sự kiện"
,
url
:
"/hoat-dong/su-kien"
,
children
:
[]
},
{
label
:
"Đào tạo"
,
url
:
"/hoat-dong/dao-tao"
,
children
:
[]
},
],
},
{
label
:
"Xuất xứ hàng hóa"
,
url
:
"/xuat-xu-hang-hoa"
,
children
:
[
{
label
:
"Định nghĩa chung"
,
url
:
"/xuat-xu-hang-hoa"
,
children
:
[]
},
{
label
:
"Mục đích của C/O"
,
url
:
"/xuat-xu-hang-hoa/muc-dich-co"
,
children
:
[]
},
{
label
:
"Luật áp dụng về C/O"
,
url
:
"/xuat-xu-hang-hoa/luat-ap-dung-co"
,
children
:
[]
},
{
label
:
"Thủ tục cấp C/O"
,
url
:
"/xuat-xu-hang-hoa/thu-tuc-cap-co"
,
children
:
[]
},
{
label
:
"Biểu mẫu C/O và cách khai"
,
url
:
"/xuat-xu-hang-hoa/bieu-mau-co"
,
children
:
[]
},
{
label
:
"Phí và lệ phí cấp C/O"
,
url
:
"/xuat-xu-hang-hoa/phi-le-phi-cap-co"
,
children
:
[]
},
{
label
:
"Điểm cấp và thời gian cấp C/O"
,
url
:
"/xuat-xu-hang-hoa/diem-cap-thoi-gian"
,
children
:
[]
},
{
label
:
"Thông tin liên hệ"
,
url
:
"/xuat-xu-hang-hoa/lien-he"
,
children
:
[]
},
],
},
{
label
:
"Đại diện giới chủ"
,
url
:
"/dai-dien-gioi-chu"
,
children
:
[
{
label
:
"Chức năng đại diện người sử dụng lao động"
,
url
:
"/dai-dien-gioi-chu/chuc-nang"
,
children
:
[]
},
{
label
:
"Sự kiện - tập huấn NSDLĐ"
,
url
:
"/dai-dien-gioi-chu/su-kien-tap-huan"
,
children
:
[]
},
{
label
:
"Tin liên quan"
,
url
:
"/dai-dien-gioi-chu/tin-lien-quan"
,
children
:
[]
},
{
label
:
"Chủ đề"
,
url
:
"/dai-dien-gioi-chu/chu-de"
,
children
:
[]
},
],
},
{
label
:
"Xúc tiến thương mại"
,
url
:
"/xuc-tien-thuong-mai"
,
children
:
[
{
label
:
"Hồ sơ thị trường"
,
url
:
"/xuc-tien-thuong-mai/ho-so-thi-truong"
,
children
:
[]
},
{
label
:
"Môi trường kinh doanh"
,
url
:
"/xuc-tien-thuong-mai/doi-song-kinh-doanh"
,
children
:
[]
},
{
label
:
"Cơ hội kinh doanh"
,
url
:
"/xuc-tien-thuong-mai/co-hoi-kinh-doanh"
,
children
:
[]
},
{
label
:
"Hỗ trợ kinh doanh"
,
url
:
"/xuc-tien-thuong-mai/ho-tro-kinh-doanh"
,
children
:
[]
},
],
},
{
label
:
"Thông tin truyền thông"
,
url
:
"/thong-tin-truyen-thong"
,
children
:
[
{
label
:
"Tin VCCI"
,
url
:
"/thong-tin-truyen-thong/tin-vcci"
,
children
:
[]
},
{
label
:
"Tin kinh tế"
,
url
:
"/thong-tin-truyen-thong/tin-kinh-te"
,
children
:
[]
},
{
label
:
"Tin doanh nghiệp"
,
url
:
"/thong-tin-truyen-thong/tin-doanh-nghiep"
,
children
:
[]
},
{
label
:
"Chuyên đề"
,
url
:
"/thong-tin-truyen-thong/chuyen-de"
,
children
:
[]
},
{
label
:
"Thông tin chính sách và pháp luật"
,
url
:
"/thong-tin-truyen-thong/chinh-sach-phap-luat"
,
children
:
[]
},
{
label
:
"Ấn phẩm"
,
url
:
"/thong-tin-truyen-thong/an-pham"
,
children
:
[]
},
{
label
:
"Thư viện tài liệu"
,
url
:
"/thong-tin-truyen-thong/thu-vien-tai-lieu"
,
children
:
[]
},
],
},
];
export
default
MOCK_SITEMAP
;
src/app/(main)/site-map/page.tsx
0 → 100644
View file @
5ca290c8
"use client"
;
import
React
from
"react"
;
import
{
MOCK_SITEMAP
}
from
"./_lib/mock-data"
;
import
Link
from
"next/link"
;
function
SiteMapPage
()
{
const
homepage
=
MOCK_SITEMAP
[
0
];
const
sections
=
MOCK_SITEMAP
.
slice
(
1
);
return
(
<
div
className=
"min-h-screen bg-gray-50 py-12"
>
<
div
className=
"container mx-auto px-4"
>
<
h1
className=
"text-3xl font-bold text-center mb-12 text-[#063e8e]"
>
SƠ ĐỒ TRANG WEB
</
h1
>
{
/* Sitemap Structure */
}
<
div
className=
"relative flex flex-col items-center"
>
{
/* Homepage - Top Level */
}
<
div
className=
"relative mb-20"
>
<
Link
href=
{
homepage
.
url
}
className=
"block bg-[#063e8e] text-white px-8 py-4 rounded-lg font-semibold text-center hover:bg-[#0a4fb5] transition shadow-lg min-w-[200px]"
>
{
homepage
.
label
.
toUpperCase
()
}
</
Link
>
{
/* Vertical line from homepage down */
}
<
div
className=
"absolute left-1/2 -translate-x-1/2 top-full h-16 w-0.5 bg-gray-600"
></
div
>
</
div
>
{
/* Main Sections - Second Level */
}
<
div
className=
"relative w-full max-w-[1400px]"
>
{
/* Horizontal line connecting all sections */
}
<
div
className=
"absolute top-0 left-[7%] right-[7%] h-0.5 bg-gray-600 z-0"
></
div
>
<
div
className=
"grid grid-cols-2 md:grid-cols-4 lg:grid-cols-7 gap-6 relative pt-4"
>
{
sections
.
map
((
section
,
idx
)
=>
(
<
div
key=
{
idx
}
className=
"relative flex flex-col items-center"
>
{
/* Vertical line from horizontal bar down to section */
}
<
div
className=
"absolute -top-4 left-1/2 -translate-x-1/2 h-4 w-0.5 bg-gray-600 z-10"
></
div
>
{
/* Section Box */
}
<
div
className=
"relative z-20"
>
<
Link
href=
{
section
.
url
}
className=
"flex bg-[#063e8e] text-white px-4 py-3 rounded-md font-medium text-center hover:bg-[#0a4fb5] transition shadow-md w-full text-sm min-h-20 items-center justify-center"
>
<
span
className=
"leading-tight"
>
{
section
.
label
.
toUpperCase
()
}
</
span
>
</
Link
>
{
/* Vertical line from section down to children */
}
{
section
.
children
&&
section
.
children
.
length
>
0
&&
(
<
div
className=
"absolute left-1/2 -translate-x-1/2 top-full h-6 w-0.5 bg-gray-600 z-10"
></
div
>
)
}
</
div
>
{
/* Children - Third Level */
}
{
section
.
children
&&
section
.
children
.
length
>
0
&&
(
<
div
className=
"mt-6 flex flex-col gap-3 w-full relative z-20"
>
{
section
.
children
.
map
((
child
,
childIdx
)
=>
(
<
div
key=
{
childIdx
}
className=
"relative"
>
{
/* Vertical line connecting child to parent */
}
{
childIdx
===
0
?
(
// First child connects to the line from parent
<
div
className=
"absolute left-1/2 -translate-x-1/2 -top-6 h-6 w-0.5 bg-gray-600"
></
div
>
)
:
(
// Other children connect to the vertical spine
<
div
className=
"absolute left-1/2 -translate-x-1/2 -top-[calc(1.5rem+0.375rem)] bottom-1/2 w-0.5 bg-gray-600"
></
div
>
)
}
{
/* Horizontal line from spine to child box */
}
<
div
className=
"absolute left-1/2 top-1/2 -translate-y-1/2 w-1/2 h-0.5 bg-gray-600 -translate-x-full"
></
div
>
<
Link
href=
{
child
.
url
}
className=
"block bg-gray-400 text-white px-3 py-2.5 rounded text-xs font-medium text-center hover:bg-gray-500 transition shadow-sm leading-tight relative z-10"
>
{
child
.
label
.
toUpperCase
()
}
</
Link
>
</
div
>
))
}
</
div
>
)
}
</
div
>
))
}
</
div
>
</
div
>
</
div
>
</
div
>
<
style
jsx
>
{
`
@media (max-width: 768px) {
.grid {
grid-template-columns: repeat(2, 1fr);
}
}
`
}
</
style
>
</
div
>
);
}
export
default
SiteMapPage
;
src/app/(main)/thong-tin-truyen-thong/chuyen-de/[id]/page.tsx
View file @
5ca290c8
...
...
@@ -20,6 +20,10 @@ 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
}
</
div
>
<
hr
className=
"py-2"
/>
<
div
className=
"p-7.5 prose tiptap overflow-hidden"
>
{
parse
(
data
?.
responseData
?.
description
??
''
)
}
</
div
>
</
main
>
...
...
src/app/(main)/thong-tin-truyen-thong/chuyen-de/page.tsx
View file @
5ca290c8
...
...
@@ -5,46 +5,58 @@ import { MEDIA_INFORMATION_CATEGORIES } from "@constants/categories";
// ...existing code...
import
NewsContent
from
"@app/dai-dien-gioi-chu/components/card-news"
;
import
ListFilter
from
"@app/dai-dien-gioi-chu/components/list-filter"
;
import
{
Pagination
}
from
"@components/base/pagination"
;
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
{
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
,
filters
:
submitSearch
?
`title @=
${
submitSearch
}
,category @=Chuyên đề`
:
'category @=Chuyên đề'
,
});
return
(
<
div
className=
"min-h-screen container mx-auto p-4"
>
<
div
className=
"w-full flex flex-col gap-5"
>
<
ListCategory
categories=
{
MEDIA_INFORMATION_CATEGORIES
}
/>
<
ListCategory
categories=
{
MEDIA_INFORMATION_CATEGORIES
}
/>
<
div
className=
"grid grid-cols-1 lg:grid-cols-3 gap-6"
>
{
/* 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}/chuyen-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 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}`
}
/>
))
}
<
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/page.tsx
View file @
5ca290c8
...
...
@@ -15,7 +15,7 @@ export default function Page() {
return
(
<
div
className=
"min-h-screen container mx-auto p-4"
>
<
div
className=
"w-full flex flex-col gap-5"
>
<
ListCategory
categories=
{
MEDIA_INFORMATION_CATEGORIES
}
/>
<
ListCategory
categories=
{
MEDIA_INFORMATION_CATEGORIES
}
/>
</
div
>
</
div
>
...
...
src/app/(main)/thong-tin-truyen-thong/thong-tin-chinh-sach-va-phap-luat/[id]/page.tsx
View file @
5ca290c8
...
...
@@ -20,6 +20,10 @@ 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
}
</
div
>
<
hr
className=
"py-2"
/>
<
div
className=
"p-7.5 prose tiptap overflow-hidden"
>
{
parse
(
data
?.
responseData
?.
description
??
''
)
}
</
div
>
</
main
>
...
...
src/app/(main)/thong-tin-truyen-thong/thong-tin-chinh-sach-va-phap-luat/page.tsx
View file @
5ca290c8
...
...
@@ -5,7 +5,7 @@ import { MEDIA_INFORMATION_CATEGORIES } from "@constants/categories";
// ...existing code...
import
NewsContent
from
"@app/dai-dien-gioi-chu/components/card-news"
;
import
ListFilter
from
"@app/dai-dien-gioi-chu/components/list-filter"
;
import
{
Pagination
}
from
"@components/base/pagination"
;
import
{
Pagination
}
from
"@components/base/pagination"
;
import
Image
from
"next/image"
;
import
{
useGetNews
}
from
"@api/endpoints/news"
;
import
{
GetNewsResponseType
}
from
"@api/types/NewsPage.type"
;
...
...
@@ -15,27 +15,30 @@ 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
}
`
:
undefined
,
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"
>
<
div
className=
"w-full flex flex-col gap-5"
>
<
ListCategory
categories=
{
MEDIA_INFORMATION_CATEGORIES
}
/>
<
ListCategory
categories=
{
MEDIA_INFORMATION_CATEGORIES
}
/>
<
div
className=
"grid grid-cols-1 lg:grid-cols-3 gap-6"
>
{
/* 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}/thong-tin-chinh-sach-va-phap-luat/${news.id}`
}
/>
))
}
{
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}/thong-tin-chinh-sach-va-phap-luat/${news.id}`
}
/>
)))
}
<
div
className=
"w-full flex justify-center mt-4"
>
<
Pagination
...
...
src/app/(main)/thong-tin-truyen-thong/thu-vien-tai-lieu/[id]/page.tsx
View file @
5ca290c8
...
...
@@ -20,6 +20,10 @@ 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
}
</
div
>
<
hr
className=
"py-2"
/>
<
div
className=
"p-7.5 prose tiptap overflow-hidden"
>
{
parse
(
data
?.
responseData
?.
description
??
''
)
}
</
div
>
</
main
>
...
...
src/app/(main)/thong-tin-truyen-thong/thu-vien-tai-lieu/page.tsx
View file @
5ca290c8
...
...
@@ -4,48 +4,60 @@ import ListCategory from "@app/dai-dien-gioi-chu/components/list-category";
import
{
MEDIA_INFORMATION_CATEGORIES
}
from
"@constants/categories"
;
// ...existing code...
import
NewsContent
from
"@app/dai-dien-gioi-chu/components/card-news"
;
import
{
Pagination
}
from
"@components/base/pagination"
;
import
{
Pagination
}
from
"@components/base/pagination"
;
import
ListFilter
from
"@app/dai-dien-gioi-chu/components/list-filter"
;
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
,
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"
>
<
div
className=
"w-full flex flex-col gap-5"
>
<
ListCategory
categories=
{
MEDIA_INFORMATION_CATEGORIES
}
/>
<
ListCategory
categories=
{
MEDIA_INFORMATION_CATEGORIES
}
/>
<
div
className=
"grid grid-cols-1 lg:grid-cols-3 gap-6"
>
{
/* 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}/thu-vien-tai-lieu/${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 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}`
}
/>
))
}
<
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/[id]/page.tsx
View file @
5ca290c8
...
...
@@ -20,6 +20,10 @@ 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
}
</
div
>
<
hr
className=
"py-2"
/>
<
div
className=
"p-7.5 prose tiptap overflow-hidden"
>
{
parse
(
data
?.
responseData
?.
description
??
''
)
}
</
div
>
</
main
>
...
...
src/app/(main)/thong-tin-truyen-thong/tin-doanh-nghiep/page.tsx
View file @
5ca290c8
...
...
@@ -5,47 +5,59 @@ import { MEDIA_INFORMATION_CATEGORIES } from "@constants/categories";
// ...existing code...
import
ListFilter
from
"@app/dai-dien-gioi-chu/components/list-filter"
;
import
NewsContent
from
"@app/dai-dien-gioi-chu/components/card-news"
;
import
{
Pagination
}
from
"@components/base/pagination"
;
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
{
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
,
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"
>
<
div
className=
"w-full flex flex-col gap-5"
>
<
ListCategory
categories=
{
MEDIA_INFORMATION_CATEGORIES
}
/>
<
ListCategory
categories=
{
MEDIA_INFORMATION_CATEGORIES
}
/>
<
div
className=
"grid grid-cols-1 lg:grid-cols-3 gap-6"
>
{
/* 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-doanh-nghiep/${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 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}`
}
/>
))
}
<
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/[id]/page.tsx
View file @
5ca290c8
...
...
@@ -20,6 +20,10 @@ 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
}
</
div
>
<
hr
className=
"py-2"
/>
<
div
className=
"p-7.5 prose tiptap overflow-hidden"
>
{
parse
(
data
?.
responseData
?.
description
??
''
)
}
</
div
>
</
main
>
...
...
src/app/(main)/thong-tin-truyen-thong/tin-kinh-te/page.tsx
View file @
5ca290c8
...
...
@@ -4,47 +4,59 @@ import ListCategory from "@app/dai-dien-gioi-chu/components/list-category";
import
{
MEDIA_INFORMATION_CATEGORIES
}
from
"@constants/categories"
;
// ...existing code...
import
NewsContent
from
"@app/dai-dien-gioi-chu/components/card-news"
;
import
{
Pagination
}
from
"@components/base/pagination"
;
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
{
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
,
filters
:
submitSearch
?
`title @=
${
submitSearch
}
,category @=Tin kinh tế`
:
'category @=Tin kinh tế'
,
});
return
(
<
div
className=
"min-h-screen container mx-auto p-4"
>
<
div
className=
"w-full flex flex-col gap-5"
>
<
ListCategory
categories=
{
MEDIA_INFORMATION_CATEGORIES
}
/>
<
ListCategory
categories=
{
MEDIA_INFORMATION_CATEGORIES
}
/>
<
div
className=
"grid grid-cols-1 lg:grid-cols-3 gap-6"
>
{
/* 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-kinh-te/${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 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}`
}
/>
))
}
<
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/[id]/page.tsx
View file @
5ca290c8
...
...
@@ -20,6 +20,10 @@ 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
}
</
div
>
<
hr
className=
"py-2"
/>
<
div
className=
"p-7.5 prose tiptap overflow-hidden"
>
{
parse
(
data
?.
responseData
?.
description
??
''
)
}
</
div
>
</
main
>
...
...
src/app/(main)/thong-tin-truyen-thong/tin-vcci/page.tsx
View file @
5ca290c8
...
...
@@ -6,17 +6,18 @@ import { MEDIA_INFORMATION_CATEGORIES } from "@constants/categories";
import
NewsContent
from
"@app/dai-dien-gioi-chu/components/card-news"
;
import
ListFilter
from
"@app/dai-dien-gioi-chu/components/list-filter"
;
import
EventCalendar
from
"@app/dai-dien-gioi-chu/components/event-calendar"
;
import
{
Pagination
}
from
"@components/base/pagination"
;
import
{
Pagination
}
from
"@components/base/pagination"
;
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
]
=
useState
(
""
);
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
,
...
...
@@ -24,36 +25,47 @@ export default function Page() {
return
(
<
div
className=
"min-h-screen container mx-auto p-4"
>
<
div
className=
"w-full flex flex-col gap-5"
>
<
ListCategory
categories=
{
MEDIA_INFORMATION_CATEGORIES
}
/>
<
ListCategory
categories=
{
MEDIA_INFORMATION_CATEGORIES
}
/>
<
div
className=
"grid grid-cols-1 lg:grid-cols-3 gap-6"
>
{
/* 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ả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}`
}
/>
))
}
<
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
>
{
/* Sidebar */
}
<
aside
className=
"space-y-6"
>
<
ListFilter
/>
<
EventCalendar
/>
<
ListFilter
onSearch=
{
setSubmitSearch
}
/>
<
EventCalendar
/>
<
div
className=
"bg-white border rounded-md overflow-hidden"
>
<
div
className=
"w-full h-56 relative bg-gray-100"
>
<
Image
...
...
src/app/(main)/xuat-xu-hang-hoa/page.tsx
View file @
5ca290c8
...
...
@@ -6,7 +6,7 @@ import Image from "next/image";
export
default
function
page
()
{
return
(
<
div
className=
"bg-[#f6f6f6]"
>
<
div
className=
"
max-w-[1200px]
m-auto flex flex-col gap-5 mb-[50px]"
>
<
div
className=
"
container
m-auto flex flex-col gap-5 mb-[50px]"
>
<
div
className=
"border-[#e5e7f2] border-[1px]"
>
<
ListCategory
/>
</
div
>
...
...
src/app/(main)/xuc-tien-thuong-mai/[id]/page.tsx
View file @
5ca290c8
...
...
@@ -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,7 +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=
"p-7.5 prose tiptap overflow-hidden"
>
{
parse
(
data
?.
responseData
?.
description
??
''
)
}
</
div
>
{
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
>
</>
)
}
</
main
>
{
/* Sidebar */
}
...
...
src/app/(main)/xuc-tien-thuong-mai/co-hoi-kinh-doanh/[id]/page.tsx
View file @
5ca290c8
...
...
@@ -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,7 +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=
"p-7.5 prose tiptap overflow-hidden"
>
{
parse
(
data
?.
responseData
?.
description
??
''
)
}
</
div
>
{
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
>
</>
)
:
(
<
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 @
5ca290c8
...
...
@@ -9,15 +9,17 @@ 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
,
// filters: submitSearch ? `title @=${submitSearch}` : undefined,
filters
:
'category@=Cơ hội kinh doanh'
});
return
(
<
div
className=
"min-h-screen container mx-auto p-4"
>
...
...
@@ -28,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 @
5ca290c8
...
...
@@ -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,7 +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=
"p-7.5 prose tiptap overflow-hidden"
>
{
parse
(
data
?.
responseData
?.
description
??
''
)
}
</
div
>
{
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
>
</>
)
:
(
<
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 @
5ca290c8
...
...
@@ -8,15 +8,17 @@ 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
,
// filters: submitSearch ? `title @=${submitSearch}` : undefined,
filters
:
'category@=Hỗ trợ kinh doanh'
});
return
(
<
div
className=
"min-h-screen container mx-auto p-4"
>
...
...
@@ -27,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 @
5ca290c8
...
...
@@ -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,7 +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=
"p-7.5 prose tiptap overflow-hidden"
>
{
parse
(
data
?.
responseData
?.
description
??
''
)
}
</
div
>
{
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
>
</>
)
:
(
<
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 @
5ca290c8
...
...
@@ -9,15 +9,17 @@ 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
,
// filters: submitSearch ? `title @=${submitSearch}` : undefined,
filters
:
'category@=Môi trường kinh doanh'
});
return
(
<
div
className=
"min-h-screen container mx-auto p-4"
>
...
...
@@ -28,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 @
5ca290c8
...
...
@@ -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/base/card-news/index.tsx
View file @
5ca290c8
...
...
@@ -2,8 +2,24 @@
import
{
NewsItem
}
from
'@app/dai-dien-gioi-chu/lib/types/NewsPage.type'
;
import
Links
from
'@links/index'
import
dayjs
from
'dayjs'
;
import
parse
from
'html-react-parser'
function
NewsContent
({
news
,
link
}:
{
news
:
NewsItem
,
link
:
string
})
{
// Helper: remove <img> tags and extract plain text from HTML
const
stripImagesAndHtml
=
(
html
?:
string
)
=>
{
if
(
!
html
)
return
''
// remove img tags first
const
withoutImgs
=
html
.
replace
(
/<img
[^
>
]
*>/gi
,
''
)
// use DOMParser on client for robust extraction
if
(
typeof
window
!==
'undefined'
&&
typeof
DOMParser
!==
'undefined'
)
{
try
{
const
doc
=
new
DOMParser
().
parseFromString
(
withoutImgs
,
'text/html'
)
return
doc
.
body
.
textContent
||
''
}
catch
{
// fallback to regex
}
}
return
withoutImgs
.
replace
(
/<
[^
>
]
*>/g
,
''
)
}
function
NewsContent
({
news
,
link
}:
{
news
:
NewsItem
,
link
:
string
})
{
return
(
<
a
...
...
@@ -14,20 +30,21 @@ function NewsContent({ news, link }: { news: NewsItem, link: string }) {
src=
{
`${Links.imageEndpoint}${news.thumbnail}`
}
alt=
{
news
.
title
}
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"
}
}
onError=
{
(
e
)
=>
{
e
.
currentTarget
.
src
=
"/img-error.png"
}
}
/>
<
div
className=
"flex-1 min-w-0 pl-0 sm:pl-4"
>
<
p
className=
"text-primary font-semibold text-base md:text-lg line-clamp-2 wrap-break-word hover:no-underline
"
>
<
p
className=
"text-primary font-semibold text-base md:text-lg hover:underline line-clamp-2 wrap-break-word
"
>
{
news
.
title
}
</
p
>
<
div
className=
"text-sm my-2 text-[#00AED5]"
>
{
dayjs
(
news
.
release_at
).
format
(
'DD/MM/YYYY'
)
}
</
div
>
<
div
className=
"text-sm text-[#777] line-clamp-3"
>
<
div
className=
"text-sm prose tiptap"
>
{
parse
(
news
.
description
)
}
</
div
>
<
div
className=
"text-sm prose tiptap"
>
{
stripImagesAndHtml
(
news
.
description
)
}
</
div
>
</
div
>
</
div
>
</
a
>
...
...
src/components/shared/editor-content/AppEditorContent.tsx
View file @
5ca290c8
...
...
@@ -4,24 +4,47 @@ import { AppEditorContentProps } from './AppEditorContent.type';
import
'./AppEditorContent.css'
;
const
AppEditorContent
:
FC
<
AppEditorContentProps
>
=
({
value
=
''
,
className
=
''
})
=>
{
const
transform
=
(
node
:
DOMNode
):
JSX
.
Element
|
null
=>
{
if
(
node
instanceof
Element
&&
node
.
tagName
===
'strong'
)
{
const
transform
=
(
node
:
DOMNode
):
JSX
.
Element
|
string
|
undefined
|
null
=>
{
// 1. Xử lý Text Node
if
(
node
instanceof
Text
)
{
return
node
.
data
;
}
if
(
!
(
node
instanceof
Element
))
return
undefined
;
const
tagName
=
node
.
tagName
.
toLowerCase
();
// ✅ FIX LỖI: Ép kiểu (as DOMNode) để Type 'ChildNode' khớp với 'DOMNode'
const
children
=
node
.
children
?
node
.
children
.
map
(
child
=>
transform
(
child
as
DOMNode
))
:
[];
// --- LOGIC XỬ LÝ THEO YÊU CẦU ---
// 2. ✅ Xóa thẻ <img>
if
(
tagName
===
'img'
)
{
return
<></>;
}
// 3. ✅ Xóa thẻ <a> nhưng giữ lại nội dung
if
(
tagName
===
'a'
)
{
// Trả về children đã được xử lý (làm phẳng thẻ <a>)
return
<>
{
children
}
</>;
}
// 4. ✅ Xử lý thẻ <strong>
if
(
tagName
===
'strong'
)
{
return
(
<
strong
className=
"custom-strong"
>
{
node
.
children
&&
Array
.
isArray
(
node
.
children
)
?
node
.
children
.
map
((
child
,
index
)
=>
{
if
(
typeof
child
===
'string'
)
{
return
child
;
}
else
if
(
child
instanceof
Text
)
{
return
child
.
data
;
}
return
null
;
})
:
null
}
{
children
}
</
strong
>
);
}
return
null
;
// 5. ✅ Render các thẻ HTML khác (Fallback)
// Trả về undefined để thư viện tự động render các thẻ còn lại (p, div, br,...)
return
undefined
;
};
return
(
...
...
@@ -31,4 +54,4 @@ const AppEditorContent: FC<AppEditorContentProps> = ({ value = '', className = '
);
};
export
default
AppEditorContent
;
export
default
AppEditorContent
;
\ No newline at end of file
src/components/ui/loading-state.tsx
0 → 100644
View file @
5ca290c8
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 @
5ca290c8
// 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