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
e18f1e9a
Commit
e18f1e9a
authored
May 19, 2026
by
Lê Bảo Hồng Đức
☄
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'feat/video-newsletter' into 'develop-news'
fix See merge request
!64
parents
8e5cfd6a
911d1d03
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
864 additions
and
650 deletions
+864
-650
index.tsx
src/app/(main)/(home)/components/events-calendar/index.tsx
+209
-76
use-home-posts.ts
src/app/(main)/(home)/lib/use-home-posts.ts
+83
-2
categories.ts
src/mockdata/categories.ts
+572
-572
No files found.
src/app/(main)/(home)/components/events-calendar/index.tsx
View file @
e18f1e9a
'use client'
;
'use client'
;
import
{
useHomePosts
,
type
HomePostItem
}
from
"@/app/(main)/(home)/lib/use-home-posts
"
;
import
Link
from
"next/link
"
;
import
{
addMonths
,
format
,
getDay
,
startOfMonth
,
subMonths
}
from
"date-fns"
;
import
{
addMonths
,
format
,
getDay
,
startOfMonth
,
subMonths
}
from
"date-fns"
;
import
dayjs
from
"dayjs"
;
import
dayjs
from
"dayjs"
;
import
{
ChevronLeft
,
ChevronRight
}
from
"lucide-react"
;
import
{
ChevronLeft
,
ChevronRight
}
from
"lucide-react"
;
import
{
useMemo
,
useState
}
from
"react"
;
import
{
useEffect
,
useMemo
,
useState
}
from
"react"
;
import
{
useEventCalendarPosts
,
type
HomePostItem
}
from
"@/app/(main)/(home)/lib/use-home-posts"
;
import
{
HoverCard
,
HoverCardContent
,
HoverCardTrigger
}
from
"@/components/ui/hover-card"
;
import
{
cn
}
from
"@/lib/utils"
;
import
{
cn
}
from
"@/lib/utils"
;
const
weekDays
=
[
"CN"
,
"T2"
,
"T3"
,
"T4"
,
"T5"
,
"T6"
,
"T7"
];
const
weekDays
=
[
"CN"
,
"T2"
,
"T3"
,
"T4"
,
"T5"
,
"T6"
,
"T7"
];
...
@@ -18,6 +20,16 @@ const isTrainingEvent = (item: HomePostItem) =>
...
@@ -18,6 +20,16 @@ const isTrainingEvent = (item: HomePostItem) =>
return
key
.
includes
(
"đào tạo"
)
||
key
.
includes
(
"dao-tao"
);
return
key
.
includes
(
"đào tạo"
)
||
key
.
includes
(
"dao-tao"
);
});
});
const
getDayVariant
=
(
items
:
HomePostItem
[])
=>
{
const
hasTraining
=
items
.
some
((
item
)
=>
isTrainingEvent
(
item
));
const
hasEvent
=
items
.
some
((
item
)
=>
!
isTrainingEvent
(
item
));
if
(
hasTraining
&&
hasEvent
)
return
"mixed"
;
if
(
hasTraining
)
return
"training"
;
if
(
hasEvent
)
return
"event"
;
return
"default"
;
};
function
EventsCalendar
({
function
EventsCalendar
({
className
,
className
,
compact
=
false
,
compact
=
false
,
...
@@ -25,28 +37,14 @@ function EventsCalendar({
...
@@ -25,28 +37,14 @@ function EventsCalendar({
className
?:
string
;
className
?:
string
;
compact
?:
boolean
;
compact
?:
boolean
;
})
{
})
{
const
{
eventCalendarPosts
}
=
useHomePosts
();
const
[
currentMonth
,
setCurrentMonth
]
=
useState
(
new
Date
());
const
firstEventDate
=
eventCalendarPosts
[
0
]?.
registrationDeadline
?
new
Date
(
eventCalendarPosts
[
0
].
registrationDeadline
)
:
new
Date
();
const
[
currentMonth
,
setCurrentMonth
]
=
useState
(
new
Date
(
firstEventDate
.
getFullYear
(),
firstEventDate
.
getMonth
(),
1
),
);
const
[
selectedDateKey
,
setSelectedDateKey
]
=
useState
<
string
|
null
>
(
null
);
const
[
selectedDateKey
,
setSelectedDateKey
]
=
useState
<
string
|
null
>
(
null
);
const
eventCalendarQuery
=
useEventCalendarPosts
(
currentMonth
);
const
monthEvents
=
eventCalendarQuery
.
data
??
[];
const
monthEvents
=
useMemo
(
useEffect
(()
=>
{
()
=>
setSelectedDateKey
(
null
);
eventCalendarPosts
.
filter
((
item
)
=>
{
},
[
currentMonth
]);
const
date
=
new
Date
(
item
.
registrationDeadline
);
return
(
date
.
getMonth
()
===
currentMonth
.
getMonth
()
&&
date
.
getFullYear
()
===
currentMonth
.
getFullYear
()
);
}),
[
currentMonth
,
eventCalendarPosts
],
);
const
days
=
useMemo
(()
=>
{
const
days
=
useMemo
(()
=>
{
const
monthStart
=
startOfMonth
(
currentMonth
);
const
monthStart
=
startOfMonth
(
currentMonth
);
...
@@ -68,14 +66,21 @@ function EventsCalendar({
...
@@ -68,14 +66,21 @@ function EventsCalendar({
const
key
=
dayjs
(
item
.
registrationDeadline
).
format
(
"YYYY-MM-DD"
);
const
key
=
dayjs
(
item
.
registrationDeadline
).
format
(
"YYYY-MM-DD"
);
const
existing
=
map
.
get
(
key
)
??
[];
const
existing
=
map
.
get
(
key
)
??
[];
existing
.
push
(
item
);
existing
.
push
(
item
);
map
.
set
(
key
,
existing
);
map
.
set
(
key
,
existing
.
sort
(
(
left
,
right
)
=>
dayjs
(
left
.
registrationDeadline
).
valueOf
()
-
dayjs
(
right
.
registrationDeadline
).
valueOf
(),
),
);
});
});
return
map
;
return
map
;
},
[
monthEvents
]);
},
[
monthEvents
]);
const
selectedEvents
=
selectedDateKey
?
eventMap
.
get
(
selectedDateKey
)
??
[]
:
[];
const
selectedEvents
=
selectedDateKey
?
eventMap
.
get
(
selectedDateKey
)
??
[]
:
[];
const
highlightedEvent
=
selectedEvents
[
0
]
??
monthEvents
[
0
];
const
highlightedEvents
=
selectedEvents
.
length
>
0
?
selectedEvents
:
monthEvents
.
slice
(
0
,
1
);
const
todayKey
=
dayjs
().
format
(
"YYYY-MM-DD"
);
return
(
return
(
<
aside
<
aside
...
@@ -112,6 +117,7 @@ function EventsCalendar({
...
@@ -112,6 +117,7 @@ function EventsCalendar({
type=
"button"
type=
"button"
onClick=
{
()
=>
setCurrentMonth
(
subMonths
(
currentMonth
,
1
))
}
onClick=
{
()
=>
setCurrentMonth
(
subMonths
(
currentMonth
,
1
))
}
className=
"flex h-8 w-8 items-center justify-center rounded-full border border-[#dbe4f2] text-[#7f8eab] transition-colors hover:border-[#24469c] hover:text-[#24469c]"
className=
"flex h-8 w-8 items-center justify-center rounded-full border border-[#dbe4f2] text-[#7f8eab] transition-colors hover:border-[#24469c] hover:text-[#24469c]"
aria
-
label=
"Tháng trước"
>
>
<
ChevronLeft
className=
"h-4 w-4"
/>
<
ChevronLeft
className=
"h-4 w-4"
/>
</
button
>
</
button
>
...
@@ -119,64 +125,144 @@ function EventsCalendar({
...
@@ -119,64 +125,144 @@ function EventsCalendar({
type=
"button"
type=
"button"
onClick=
{
()
=>
setCurrentMonth
(
addMonths
(
currentMonth
,
1
))
}
onClick=
{
()
=>
setCurrentMonth
(
addMonths
(
currentMonth
,
1
))
}
className=
"flex h-8 w-8 items-center justify-center rounded-full border border-[#dbe4f2] text-[#7f8eab] transition-colors hover:border-[#24469c] hover:text-[#24469c]"
className=
"flex h-8 w-8 items-center justify-center rounded-full border border-[#dbe4f2] text-[#7f8eab] transition-colors hover:border-[#24469c] hover:text-[#24469c]"
aria
-
label=
"Tháng sau"
>
>
<
ChevronRight
className=
"h-4 w-4"
/>
<
ChevronRight
className=
"h-4 w-4"
/>
</
button
>
</
button
>
</
div
>
</
div
>
</
div
>
</
div
>
<
div
className=
{
cn
(
"h-[4px] w-[60px] rounded-full bg-[#f7b500]"
,
compact
?
"mt-2.5"
:
"mt-3"
)
}
/>
<
div
className=
{
cn
(
"mt-3 h-[4px] w-[60px] rounded-full bg-[#f7b500]"
,
compact
&&
"mt-2.5"
)
}
/>
<
div
className=
{
cn
(
"border-t border-[#ebf0f8] pt-3.5"
,
compact
?
"mt-3"
:
"mt-4"
)
}
>
<
div
className=
{
cn
(
"mt-4 border-t border-[#ebf0f8] pt-3.5"
,
compact
&&
"mt-3"
)
}
>
{
eventCalendarQuery
.
isLoading
?
(
<
div
className=
"mb-3 rounded-[16px] bg-[#f7f9fd] p-3 text-[12px] text-[#3d547f]"
>
Đang tải dữ liệu tháng này...
</
div
>
)
:
null
}
<
div
className=
"grid grid-cols-7 gap-y-2.5 text-center text-[11px] font-semibold uppercase text-[#9aabc6]"
>
<
div
className=
"grid grid-cols-7 gap-y-2.5 text-center text-[11px] font-semibold uppercase text-[#9aabc6]"
>
{
weekDays
.
map
((
day
)
=>
(
{
weekDays
.
map
((
day
)
=>
(
<
div
key=
{
day
}
>
{
day
}
</
div
>
<
div
key=
{
day
}
>
{
day
}
</
div
>
))
}
))
}
</
div
>
</
div
>
<
div
className=
"mt-2.5 grid grid-cols-7 gap-y-
2.5
text-center text-[13px] text-[#5e7090]"
>
<
div
className=
"mt-2.5 grid grid-cols-7 gap-y-
3
text-center text-[13px] text-[#5e7090]"
>
{
days
.
map
((
day
)
=>
{
{
days
.
map
((
day
)
=>
{
const
key
=
dayjs
(
day
).
format
(
"YYYY-MM-DD"
);
const
key
=
dayjs
(
day
).
format
(
"YYYY-MM-DD"
);
const
items
=
eventMap
.
get
(
key
)
??
[];
const
items
=
eventMap
.
get
(
key
)
??
[];
const
inMonth
=
day
.
getMonth
()
===
currentMonth
.
getMonth
();
const
inMonth
=
day
.
getMonth
()
===
currentMonth
.
getMonth
();
const
hasTraining
=
items
.
some
((
item
)
=>
isTrainingEvent
(
item
));
const
hasEvent
=
items
.
length
>
0
&&
!
hasTraining
;
const
tooltip
=
items
.
map
((
item
)
=>
item
.
title
).
join
(
"
\n
"
);
const
selectable
=
inMonth
&&
items
.
length
>
0
;
const
selectable
=
inMonth
&&
items
.
length
>
0
;
const
selected
=
selectable
&&
selectedDateKey
===
key
;
const
selected
=
selectable
&&
selectedDateKey
===
key
;
const
isToday
=
key
===
todayKey
;
const
variant
=
getDayVariant
(
items
);
return
(
const
dayButton
=
(
<
div
<
button
key=
{
key
}
type=
"button"
className=
"relative flex items-center justify-center"
disabled=
{
!
selectable
}
onClick=
{
()
=>
setSelectedDateKey
(
key
)
}
aria
-
label=
{
selectable
?
`${format(day, "dd/MM/yyyy")} có ${items.length} hoạt động`
:
format
(
day
,
"dd/MM/yyyy"
)
}
className=
{
cn
(
"relative flex h-8 w-8 items-center justify-center rounded-full text-[13px] transition-all sm:h-9 sm:w-9"
,
!
inMonth
&&
"text-[#c9d2e2]"
,
isToday
&&
inMonth
&&
!
selectable
&&
"bg-[#eef3fb] font-semibold text-[#24469c] ring-2 ring-[#d7e2f5]"
,
variant
===
"training"
&&
"bg-[#ffbc11] font-semibold text-[#163b73]"
,
variant
===
"event"
&&
"bg-[#1e3f9a] font-semibold text-white"
,
variant
===
"mixed"
&&
"bg-[#1e3f9a] font-semibold text-white ring-2 ring-[#ffbc11] ring-offset-2 ring-offset-white"
,
selectable
?
"cursor-pointer hover:scale-[1.04] hover:shadow-[0_10px_20px_rgba(36,70,156,0.16)]"
:
"cursor-default"
,
selected
&&
variant
!==
"mixed"
&&
"ring-2 ring-[#f7b500] ring-offset-2 ring-offset-white"
,
isToday
&&
selectable
&&
!
selected
&&
variant
!==
"mixed"
&&
"ring-2 ring-[#9fb3db] ring-offset-2 ring-offset-white"
,
)
}
>
>
<
button
{
format
(
day
,
"d"
)
}
type=
"button"
{
items
.
length
>
1
?
(
title=
{
tooltip
||
undefined
}
<
span
className=
"absolute -right-1 -top-1 flex h-4 min-w-4 items-center justify-center rounded-full bg-[#f7b500] px-1 text-[10px] font-bold leading-none text-[#163b73] shadow-sm"
>
disabled=
{
!
selectable
}
{
items
.
length
}
onClick=
{
()
=>
setSelectedDateKey
(
key
)
}
</
span
>
className=
{
`relative flex h-7 w-7 items-center justify-center rounded-full transition-all ${
)
:
null
}
!inMonth
{
isToday
?
(
? "text-[#c9d2e2]"
<
span
className=
"absolute -bottom-5 left-1/2 -translate-x-1/2 whitespace-nowrap text-[9px] font-semibold uppercase tracking-[0.14em] text-[#7f8eab]"
></
span
>
: hasTraining
? "bg-[#ffbc11] font-semibold text-[#163b73]"
: hasEvent
? "bg-[#1e3f9a] font-semibold text-white"
: ""
} ${
selectable
? "cursor-pointer hover:ring-2 hover:ring-[#f7b500]/60"
: "cursor-default"
} ${selected ? "ring-2 ring-[#f7b500] ring-offset-2" : ""}`
}
>
{
format
(
day
,
"d"
)
}
</
button
>
{
items
.
length
>
0
&&
!
hasTraining
&&
inMonth
?
(
<
span
className=
"absolute bottom-[-5px] h-1.5 w-1.5 rounded-full bg-[#1e3f9a]"
/>
)
:
null
}
)
:
null
}
</
button
>
);
return
(
<
div
key=
{
key
}
className=
"relative flex items-center justify-center"
>
{
selectable
?
(
<
HoverCard
openDelay=
{
90
}
closeDelay=
{
120
}
>
<
HoverCardTrigger
asChild
>
{
dayButton
}
</
HoverCardTrigger
>
<
HoverCardContent
side=
"top"
align=
"center"
sideOffset=
{
12
}
className=
"hidden w-[min(360px,calc(100vw-2rem))] overflow-hidden rounded-[20px] border border-[#d9e3f2] bg-white p-0 text-[#234171] shadow-[0_20px_45px_rgba(16,61,130,0.18)] lg:block"
>
<
div
className=
"flex items-center justify-between gap-3 border-b border-[#edf2f9] px-4 py-3"
>
<
p
className=
"text-[11px] font-semibold uppercase tracking-[0.22em] text-[#7f8eab]"
>
{
format
(
day
,
"dd/MM/yyyy"
)
}
</
p
>
<
p
className=
"shrink-0 text-sm font-semibold text-[#24469c]"
>
{
items
.
length
===
1
?
"1 hoạt động"
:
`${items.length} hoạt động`
}
</
p
>
</
div
>
{
items
.
length
>
0
&&
hasTraining
&&
inMonth
?
(
<
div
className=
"calendar-hover-scroll max-h-[260px] space-y-2.5 overflow-y-auto px-3 py-3"
>
<
span
className=
"absolute bottom-[-5px] h-1.5 w-1.5 rounded-full bg-[#ffbc11]"
/>
{
items
.
map
((
item
)
=>
(
<
Link
key=
{
item
.
id
}
href=
{
item
.
externalLink
||
"#"
}
className=
"block rounded-[16px] border border-[#e3ebf8] bg-[#fbfdff] px-3.5 py-3 transition-colors hover:border-[#c9d7ee] hover:bg-white"
>
<
div
className=
"flex items-start gap-2.5"
>
<
span
className=
{
cn
(
"mt-1.5 h-2.5 w-2.5 shrink-0 rounded-full"
,
isTrainingEvent
(
item
)
?
"bg-[#ffbc11]"
:
"bg-[#1e3f9a]"
,
)
}
/>
<
div
className=
"min-w-0 flex-1"
>
<
p
className=
"line-clamp-2 text-[13px] font-semibold leading-5 text-[#1f3768]"
>
{
item
.
title
}
</
p
>
<
div
className=
"mt-2 flex flex-wrap items-center gap-x-3 gap-y-1 text-[11px] text-[#6f84aa]"
>
<
span
>
Hạn đăng ký:
{
formatDateTime
(
item
.
registrationDeadline
)
}
</
span
>
<
span
>
Chi phí:
{
item
.
participationFee
||
"Đang cập nhật"
}
</
span
>
</
div
>
<
div
className=
"mt-1 flex flex-wrap items-center gap-x-3 gap-y-1 text-[11px] text-[#6f84aa]"
>
<
span
>
Địa điểm:
{
item
.
location
||
"Đang cập nhật"
}
</
span
>
</
div
>
</
div
>
</
div
>
</
Link
>
))
}
</
div
>
</
HoverCardContent
>
</
HoverCard
>
)
:
(
dayButton
)
}
{
items
.
length
>
0
&&
inMonth
?
(
<
span
className=
{
cn
(
"absolute bottom-[-5px] h-1.5 w-1.5 rounded-full"
,
variant
===
"training"
&&
"bg-[#ffbc11]"
,
variant
===
"event"
&&
"bg-[#1e3f9a]"
,
variant
===
"mixed"
&&
"bg-[#24469c] shadow-[0_0_0_2px_#ffbc11]"
,
)
}
/>
)
:
null
}
)
:
null
}
</
div
>
</
div
>
);
);
...
@@ -184,35 +270,82 @@ function EventsCalendar({
...
@@ -184,35 +270,82 @@ function EventsCalendar({
</
div
>
</
div
>
</
div
>
</
div
>
<
div
className=
"mt-
4 flex flex-wrap items-center gap-x-5 gap-y-2
text-[12px] font-medium text-[#45608f]"
>
<
div
className=
"mt-
6 flex flex-wrap items-center justify-center gap-x-6 gap-y-2 text-center
text-[12px] font-medium text-[#45608f]"
>
<
div
className=
"flex items-center gap-2"
>
<
div
className=
"flex items-center
justify-center
gap-2"
>
<
span
className=
"h-2.5 w-2.5 rounded-full bg-[#1e3f9a]"
/>
<
span
className=
"h-2.5 w-2.5 rounded-full bg-[#1e3f9a]"
/>
<
span
>
Sự kiện
</
span
>
<
span
>
Sự kiện
</
span
>
</
div
>
</
div
>
<
div
className=
"flex items-center gap-2"
>
<
div
className=
"flex items-center
justify-center
gap-2"
>
<
span
className=
"h-2.5 w-2.5 rounded-full bg-[#ffbc11]"
/>
<
span
className=
"h-2.5 w-2.5 rounded-full bg-[#ffbc11]"
/>
<
span
>
Đào tạo
</
span
>
<
span
>
Đào tạo
</
span
>
</
div
>
</
div
>
</
div
>
</
div
>
{
highlightedEvent
?
(
{
highlightedEvents
.
length
>
0
?
(
<
div
className=
"mt-4 rounded-[16px] bg-[#f7f9fd] p-3.5 text-[12px] leading-5 text-[#3d547f]"
>
<
div
className=
"mt-4 rounded-2xl bg-[#f7f9fd] p-3.5 text-[12px] leading-5 text-[#3d547f] lg:hidden"
>
<
div
className=
"flex items-start gap-3"
>
{
selectedEvents
.
length
>
1
?
(
<
span
<
div
className=
"mb-3 flex items-center justify-between gap-3 border-b border-[#e5edf8] pb-2.5"
>
className=
{
`mt-1 h-2.5 w-2.5 shrink-0 rounded-full ${
<
p
className=
"text-[12px] font-semibold text-[#24469c]"
>
isTrainingEvent(highlightedEvent) ? "bg-[#ffbc11]" : "bg-[#1e3f9a]"
{
selectedEvents
.
length
}
hoạt động trong ngày này
}`
}
/>
<
div
className=
"min-w-0 space-y-1"
>
<
p
>
Hạn đăng ký:
{
formatDateTime
(
highlightedEvent
.
registrationDeadline
)
}
· Chi phí:
{
" "
}
{
highlightedEvent
.
participationFee
||
"Đang cập nhật"
}
</
p
>
</
p
>
<
p
>
Địa điểm:
{
highlightedEvent
.
location
||
"Đang cập nhật"
}
</
p
>
</
div
>
</
div
>
)
:
null
}
<
div
className=
"space-y-3"
>
{
highlightedEvents
.
map
((
item
)
=>
(
<
div
key=
{
item
.
id
}
className=
"rounded-[14px] bg-white/70 px-3 py-2.5"
>
<
div
className=
"flex items-start gap-3"
>
<
span
className=
{
cn
(
"mt-1 h-2.5 w-2.5 shrink-0 rounded-full"
,
isTrainingEvent
(
item
)
?
"bg-[#ffbc11]"
:
"bg-[#1e3f9a]"
,
)
}
/>
<
div
className=
"min-w-0 space-y-1"
>
<
Link
href=
{
item
.
externalLink
||
"#"
}
className=
"line-clamp-2 text-[13px] font-semibold leading-5 text-[#1f3768] hover:text-[#24469c]"
>
{
item
.
title
}
</
Link
>
<
p
>
Hạn đăng ký:
{
formatDateTime
(
item
.
registrationDeadline
)
}
· Chi phí:
{
" "
}
{
item
.
participationFee
||
"Đang cập nhật"
}
</
p
>
<
p
>
Địa điểm:
{
item
.
location
||
"Đang cập nhật"
}
</
p
>
</
div
>
</
div
>
</
div
>
))
}
</
div
>
</
div
>
</
div
>
</
div
>
)
:
null
}
)
:
null
}
<
style
jsx
>
{
`
.calendar-hover-scroll {
scrollbar-width: thin;
scrollbar-color: #9fb3db #eef3fb;
}
.calendar-hover-scroll::-webkit-scrollbar {
width: 8px;
}
.calendar-hover-scroll::-webkit-scrollbar-track {
border-radius: 9999px;
background: #eef3fb;
}
.calendar-hover-scroll::-webkit-scrollbar-thumb {
border: 2px solid #eef3fb;
border-radius: 9999px;
background: linear-gradient(180deg, #24469c 0%, #5a76bd 100%);
}
.calendar-hover-scroll::-webkit-scrollbar-thumb:hover {
background: linear-gradient(180deg, #1d3a86 0%, #4f6bb2 100%);
}
`
}
</
style
>
</
aside
>
</
aside
>
);
);
}
}
...
...
src/app/(main)/(home)/lib/use-home-posts.ts
View file @
e18f1e9a
...
@@ -2,6 +2,7 @@
...
@@ -2,6 +2,7 @@
import
*
as
React
from
"react"
;
import
*
as
React
from
"react"
;
import
{
useQuery
}
from
"@tanstack/react-query"
;
import
{
useQuery
}
from
"@tanstack/react-query"
;
import
dayjs
from
"dayjs"
;
import
{
useCustomClient
}
from
"@/api/mutator/custom-client"
;
import
{
useCustomClient
}
from
"@/api/mutator/custom-client"
;
import
Links
,
{
resolveUploadUrl
}
from
"@/links"
;
import
Links
,
{
resolveUploadUrl
}
from
"@/links"
;
...
@@ -83,7 +84,7 @@ export type HomePostItem = {
...
@@ -83,7 +84,7 @@ export type HomePostItem = {
}
|
null
;
}
|
null
;
};
};
const
HOME_POSTS_QUERY_KEY
=
[
"home-page-posts"
,
"
event-calendar-v1
"
]
as
const
;
const
HOME_POSTS_QUERY_KEY
=
[
"home-page-posts"
,
"
featured-page-size-3
"
]
as
const
;
const
HOME_CATEGORY_NAMES
=
{
const
HOME_CATEGORY_NAMES
=
{
tinVcci
:
"Tin VCCI"
,
tinVcci
:
"Tin VCCI"
,
...
@@ -251,10 +252,29 @@ function createCategoryPostsQuery(categoryId: string, pageSize: string) {
...
@@ -251,10 +252,29 @@ function createCategoryPostsQuery(categoryId: string, pageSize: string) {
});
});
}
}
function
createEventCalendarQuery
(
currentMonth
:
Date
)
{
const
monthStart
=
new
Date
(
currentMonth
.
getFullYear
(),
currentMonth
.
getMonth
(),
1
);
const
monthEnd
=
new
Date
(
currentMonth
.
getFullYear
(),
currentMonth
.
getMonth
()
+
1
,
0
,
23
,
59
,
59
,
999
);
return
new
URLSearchParams
({
sortField
:
"registration_deadline"
,
sortOrder
:
"asc"
,
filters
:
[
`category.id==(
${
HOME_CATEGORY_IDS
.
suKien
}
|
${
HOME_CATEGORY_IDS
.
daoTao
}
)`
,
`registration_deadline>=
${
dayjs
(
monthStart
).
format
(
"YYYY-MM-DD HH:mm:ss"
)}
`
,
`registration_deadline<=
${
dayjs
(
monthEnd
).
format
(
"YYYY-MM-DD HH:mm:ss"
)}
`
,
"is_hidden==false"
,
"is_active==true"
,
"status==published"
,
"type==news"
,
].
join
(
","
),
});
}
async
function
fetchHomePosts
()
{
async
function
fetchHomePosts
()
{
const
featuredQuery
=
new
URLSearchParams
({
const
featuredQuery
=
new
URLSearchParams
({
page
:
"1"
,
page
:
"1"
,
pageSize
:
"
10
"
,
pageSize
:
"
3
"
,
sortField
:
"release_at"
,
sortField
:
"release_at"
,
sortOrder
:
"desc"
,
sortOrder
:
"desc"
,
filters
:
[
filters
:
[
...
@@ -517,3 +537,64 @@ export function useHomePosts() {
...
@@ -517,3 +537,64 @@ export function useHomePosts() {
categoryNames
:
HOME_CATEGORY_NAMES
,
categoryNames
:
HOME_CATEGORY_NAMES
,
};
};
}
}
export
function
useEventCalendarPosts
(
currentMonth
:
Date
)
{
const
query
=
useQuery
({
queryKey
:
[
"event-calendar-posts"
,
currentMonth
.
getFullYear
(),
currentMonth
.
getMonth
()],
queryFn
:
async
()
=>
{
const
queryParams
=
createEventCalendarQuery
(
currentMonth
);
const
response
=
await
useCustomClient
<
HomeEnvelope
<
HomePagedResult
<
RawHomePost
>>>
(
`/post?
${
queryParams
.
toString
()}
`
,
);
return
(
response
.
responseData
?.
rows
??
[]).
map
((
item
)
=>
{
const
categories
=
(
item
.
categories
??
[])
.
filter
((
category
)
=>
category
?.
id
&&
category
?.
name
)
.
map
((
category
)
=>
({
id
:
String
(
category
.
id
),
name
:
String
(
category
.
name
),
slug
:
String
(
category
.
slug
??
""
),
url
:
normalizeLink
(
category
.
url
,
"#"
),
type
:
String
(
category
.
type
??
""
),
}));
const
thumbnailPath
=
item
.
thumbnail
?.
path
??
item
.
thumbnail
?.
original
??
null
;
const
title
=
String
(
item
.
title
??
""
).
trim
();
const
externalLink
=
normalizeLink
(
item
.
external_link
||
(
title
?
`/
${
title
}
`
:
undefined
),
"#"
,
);
return
{
id
:
String
(
item
.
id
??
""
),
title
,
externalLink
,
summary
:
String
(
item
.
summary
??
item
.
content
??
""
),
createdAt
:
String
(
item
.
created_at
??
""
),
publishedAt
:
String
(
item
.
published_at
??
item
.
release_at
??
item
.
created_at
??
""
),
startedAt
:
String
(
item
.
started_at
??
""
),
endedAt
:
String
(
item
.
ended_at
??
""
),
registrationDeadline
:
String
(
item
.
registration_deadline
??
""
),
location
:
String
(
item
.
location
??
""
),
participationFee
:
String
(
item
.
participation_fee
??
""
),
expiredAt
:
String
(
item
.
expired_at
??
""
),
isFeatured
:
Boolean
(
item
.
is_featured
),
isHidden
:
Boolean
(
item
.
is_hidden
),
isActive
:
item
.
is_active
!==
false
,
status
:
String
(
item
.
status
??
""
),
type
:
String
(
item
.
type
??
""
),
categories
,
thumbnail
:
thumbnailPath
?
{
url
:
resolveAssetUrl
(
thumbnailPath
),
alt
:
title
,
}
:
null
,
}
satisfies
HomePostItem
;
});
},
staleTime
:
5
*
60
*
1000
,
});
return
query
;
}
src/mockdata/categories.ts
View file @
e18f1e9a
...
@@ -2,578 +2,578 @@ import type { Category } from "@/api/models/category";
...
@@ -2,578 +2,578 @@ import type { Category } from "@/api/models/category";
export
const
categoryFallbackRows
:
Category
[]
=
[
export
const
categoryFallbackRows
:
Category
[]
=
[
{
{
id
:
"d7f05384-b1b4-428e-b9b3-37e0e1b0cec
d"
,
"id"
:
"9adf2741-f2ee-4a0a-88a2-0b6fd8d9adf
d"
,
name
:
"Ấn phẩm
"
,
"name"
:
"Tin Doanh nghiệp
"
,
slug
:
"an-pham
"
,
"slug"
:
"tin-doanh-nghiep
"
,
url
:
"/thong-tin-truyen-thong/an-pham
"
,
"url"
:
"/thong-tin-truyen-thong/tin-doanh-nghiep
"
,
sort_order
:
6
,
"created_at"
:
"2026-05-14T04:54:26.127Z"
,
created_at
:
"2026-05-14T04:54:26.127Z"
,
"created_by"
:
null
,
created_by
:
null
,
"updated_at"
:
"2026-05-16T14:12:23.732Z"
,
updated_at
:
"2026-05-14T16:17:18.677Z
"
,
"updated_by"
:
"aff87dea-73a3-4076-b1be-6b0b7b59a21d
"
,
updated_by
:
"aff87dea-73a3-4076-b1be-6b0b7b59a21d
"
,
"type"
:
"news
"
,
type
:
"news
"
,
"parent_id"
:
"23dc501f-93bb-41d7-b05e-ace02a65cfd7
"
,
parent_id
:
"23dc501f-93bb-41d7-b05e-ace02a65cfd7"
,
"sort_order"
:
3
,
thumbnail
:
null
,
"thumbnail"
:
null
},
},
{
{
id
:
"cc448be9-b9ea-46a8-aa7b-0584803330e8"
,
"id"
:
"cc448be9-b9ea-46a8-aa7b-0584803330e8"
,
name
:
"Thông tin Chính sách và Pháp luật"
,
"name"
:
"Thông tin Chính sách và Pháp luật"
,
slug
:
"thong-tin-chinh-sach-va-phap-luat"
,
"slug"
:
"thong-tin-chinh-sach-va-phap-luat"
,
url
:
"/thong-tin-truyen-thong/thong-tin-chinh-sach-va-phap-luat"
,
"url"
:
"/thong-tin-truyen-thong/thong-tin-chinh-sach-va-phap-luat"
,
sort_order
:
5
,
"created_at"
:
"2026-05-14T04:54:26.127Z"
,
created_at
:
"2026-05-14T04:54:26.127Z"
,
"created_by"
:
null
,
created_by
:
null
,
"updated_at"
:
"2026-05-16T14:12:24.075Z"
,
updated_at
:
"2026-05-14T16:16:40.326Z
"
,
"updated_by"
:
"aff87dea-73a3-4076-b1be-6b0b7b59a21d
"
,
updated_by
:
"aff87dea-73a3-4076-b1be-6b0b7b59a21d
"
,
"type"
:
"news
"
,
type
:
"news
"
,
"parent_id"
:
"23dc501f-93bb-41d7-b05e-ace02a65cfd7
"
,
parent_id
:
"23dc501f-93bb-41d7-b05e-ace02a65cfd7"
,
"sort_order"
:
5
,
thumbnail
:
null
,
"thumbnail"
:
null
},
},
{
{
id
:
"8e7090e5-bfc3-4128-81a5-37ec78c33bad
"
,
"id"
:
"64fb1b58-3d4b-470f-a506-d45268d4e847
"
,
name
:
"Chuyên đề
"
,
"name"
:
"Hỗ trợ kinh doanh
"
,
slug
:
"chuyen-de
"
,
"slug"
:
"ho-tro-kinh-doanh
"
,
url
:
"/thong-tin-truyen-thong/chuyen-de
"
,
"url"
:
"/xuc-tien-thuong-mai/ho-tro-kinh-doanh
"
,
sort_order
:
4
,
"created_at"
:
"2026-05-14T04:54:26.127Z"
,
created_at
:
"2026-05-14T04:54:26.127Z"
,
"created_by"
:
null
,
created_by
:
null
,
"updated_at"
:
"2026-05-16T14:12:23.915Z"
,
updated_at
:
"2026-05-14T16:16:25.153Z
"
,
"updated_by"
:
"aff87dea-73a3-4076-b1be-6b0b7b59a21d
"
,
updated_by
:
"aff87dea-73a3-4076-b1be-6b0b7b59a21d
"
,
"type"
:
"news
"
,
type
:
"news
"
,
"parent_id"
:
"c66f9e44-8422-4a67-a1e5-f90e3445d87e
"
,
parent_id
:
"23dc501f-93bb-41d7-b05e-ace02a65cfd7"
,
"sort_order"
:
4
,
thumbnail
:
null
,
"thumbnail"
:
null
},
},
{
{
id
:
"64fb1b58-3d4b-470f-a506-d45268d4e847
"
,
"id"
:
"8e7090e5-bfc3-4128-81a5-37ec78c33bad
"
,
name
:
"Hỗ trợ kinh doanh
"
,
"name"
:
"Chuyên đề
"
,
slug
:
"ho-tro-kinh-doanh
"
,
"slug"
:
"chuyen-de
"
,
url
:
"/xuc-tien-thuong-mai/ho-tro-kinh-doanh
"
,
"url"
:
"/thong-tin-truyen-thong/chuyen-de
"
,
sort_order
:
4
,
"created_at"
:
"2026-05-14T04:54:26.127Z"
,
created_at
:
"2026-05-14T04:54:26.127Z"
,
"created_by"
:
null
,
created_by
:
null
,
"updated_at"
:
"2026-05-16T14:12:23.853Z"
,
updated_at
:
"2026-05-14T16:15:05.682Z
"
,
"updated_by"
:
"aff87dea-73a3-4076-b1be-6b0b7b59a21d
"
,
updated_by
:
"aff87dea-73a3-4076-b1be-6b0b7b59a21d
"
,
"type"
:
"news
"
,
type
:
"news
"
,
"parent_id"
:
"b85f6710-bcbc-4c0b-8b3a-09fff0e5e51a
"
,
parent_id
:
"c66f9e44-8422-4a67-a1e5-f90e3445d87e"
,
"sort_order"
:
4
,
thumbnail
:
null
,
"thumbnail"
:
null
},
},
{
{
id
:
"ebe30f9c-d7e5-411b-a7ca-ae851118e200
"
,
"id"
:
"d7f05384-b1b4-428e-b9b3-37e0e1b0cecd
"
,
name
:
"Điểm cấp và Thời gian cấp C/O
"
,
"name"
:
"Ấn phẩm
"
,
slug
:
"diem-cap-va-thoi-gian-cap-co
"
,
"slug"
:
"an-pham
"
,
url
:
"/xuat-xu-hang-hoa/diem-cap-va-thoi-gian-cap-co
"
,
"url"
:
"/thong-tin-truyen-thong/an-pham
"
,
sort_order
:
7
,
"created_at"
:
"2026-05-14T04:54:26.127Z"
,
created_at
:
"2026-05-14T04:54:26.127Z"
,
"created_by"
:
null
,
created_by
:
null
,
"updated_at"
:
"2026-05-14T16:17:18.677Z"
,
updated_at
:
"2026-05-14T16:13:57.088Z
"
,
"updated_by"
:
"aff87dea-73a3-4076-b1be-6b0b7b59a21d
"
,
updated_by
:
"aff87dea-73a3-4076-b1be-6b0b7b59a21d
"
,
"type"
:
"news
"
,
type
:
"page
"
,
"parent_id"
:
"23dc501f-93bb-41d7-b05e-ace02a65cfd7
"
,
parent_id
:
"69b4c7e7-28ea-41f2-97f4-988fe702a8a3"
,
"sort_order"
:
6
,
thumbnail
:
null
,
"thumbnail"
:
null
},
},
{
{
id
:
"9adf2741-f2ee-4a0a-88a2-0b6fd8d9adfd
"
,
"id"
:
"755106b6-1aca-47dc-9a9c-d434736c33a1
"
,
name
:
"Tin Doanh nghiệp
"
,
"name"
:
"Tin Kinh tế
"
,
slug
:
"tin-doanh-nghiep
"
,
"slug"
:
"tin-kinh-te
"
,
url
:
"/thong-tin-truyen-thong/tin-doanh-nghiep
"
,
"url"
:
"/thong-tin-truyen-thong/tin-kinh-te
"
,
sort_order
:
3
,
"created_at"
:
"2026-05-14T04:54:26.127Z"
,
created_at
:
"2026-05-14T04:54:26.127Z"
,
"created_by"
:
null
,
created_by
:
null
,
"updated_at"
:
"2026-05-16T14:12:23.763Z"
,
updated_at
:
"2026-05-14T16:16:19.559Z
"
,
"updated_by"
:
"aff87dea-73a3-4076-b1be-6b0b7b59a21d
"
,
updated_by
:
"aff87dea-73a3-4076-b1be-6b0b7b59a21d
"
,
"type"
:
"news
"
,
type
:
"news
"
,
"parent_id"
:
"23dc501f-93bb-41d7-b05e-ace02a65cfd7
"
,
parent_id
:
"23dc501f-93bb-41d7-b05e-ace02a65cfd7"
,
"sort_order"
:
2
,
thumbnail
:
null
,
"thumbnail"
:
null
},
},
{
{
id
:
"b89b2ba6-a699-47cb-87e4-0643aea549a9
"
,
"id"
:
"ebe30f9c-d7e5-411b-a7ca-ae851118e200
"
,
name
:
"Tin VCCI
"
,
"name"
:
"Điểm cấp và Thời gian cấp C/O
"
,
slug
:
"tin-vcci
"
,
"slug"
:
"diem-cap-va-thoi-gian-cap-co
"
,
url
:
"/thong-tin-truyen-thong/tin-vcci
"
,
"url"
:
"/xuat-xu-hang-hoa/diem-cap-va-thoi-gian-cap-co
"
,
sort_order
:
1
,
"created_at"
:
"2026-05-14T04:54:26.127Z"
,
created_at
:
"2026-05-14T04:54:26.127Z"
,
"created_by"
:
null
,
created_by
:
null
,
"updated_at"
:
"2026-05-14T16:13:57.088Z"
,
updated_at
:
"2026-05-14T16:15:36.858Z
"
,
"updated_by"
:
"aff87dea-73a3-4076-b1be-6b0b7b59a21d
"
,
updated_by
:
"aff87dea-73a3-4076-b1be-6b0b7b59a21d
"
,
"type"
:
"page
"
,
type
:
"news
"
,
"parent_id"
:
"69b4c7e7-28ea-41f2-97f4-988fe702a8a3
"
,
parent_id
:
"23dc501f-93bb-41d7-b05e-ace02a65cfd7"
,
"sort_order"
:
7
,
thumbnail
:
null
,
"thumbnail"
:
null
},
},
{
{
id
:
"0a460499-89c1-4f52-8592-1fb7bb69c4a2
"
,
"id"
:
"b89b2ba6-a699-47cb-87e4-0643aea549a9
"
,
name
:
"Cơ hội kinh doanh
"
,
"name"
:
"Tin VCCI
"
,
slug
:
"co-hoi-kinh-doanh
"
,
"slug"
:
"tin-vcci
"
,
url
:
"/xuc-tien-thuong-mai/co-hoi-kinh-doanh
"
,
"url"
:
"/thong-tin-truyen-thong/tin-vcci
"
,
sort_order
:
3
,
"created_at"
:
"2026-05-14T04:54:26.127Z"
,
created_at
:
"2026-05-14T04:54:26.127Z"
,
"created_by"
:
null
,
created_by
:
null
,
"updated_at"
:
"2026-05-16T14:12:23.795Z"
,
updated_at
:
"2026-05-14T16:15:01.518Z
"
,
"updated_by"
:
"aff87dea-73a3-4076-b1be-6b0b7b59a21d
"
,
updated_by
:
"aff87dea-73a3-4076-b1be-6b0b7b59a21d
"
,
"type"
:
"news
"
,
type
:
"news
"
,
"parent_id"
:
"23dc501f-93bb-41d7-b05e-ace02a65cfd7
"
,
parent_id
:
"c66f9e44-8422-4a67-a1e5-f90e3445d87e"
,
"sort_order"
:
1
,
thumbnail
:
null
,
"thumbnail"
:
null
},
},
{
{
id
:
"90305ea7-2048-4152-8d58-ce5d1fbdf07a
"
,
"id"
:
"0a460499-89c1-4f52-8592-1fb7bb69c4a2
"
,
name
:
"Môi trường
kinh doanh"
,
"name"
:
"Cơ hội
kinh doanh"
,
slug
:
"moi-truong
-kinh-doanh"
,
"slug"
:
"co-hoi
-kinh-doanh"
,
url
:
"/xuc-tien-thuong-mai/moi-truong
-kinh-doanh"
,
"url"
:
"/xuc-tien-thuong-mai/co-hoi
-kinh-doanh"
,
sort_order
:
2
,
"created_at"
:
"2026-05-14T04:54:26.127Z"
,
created_at
:
"2026-05-14T04:54:26.127Z"
,
"created_by"
:
null
,
created_by
:
null
,
"updated_at"
:
"2026-05-16T14:12:23.883Z"
,
updated_at
:
"2026-05-14T16:14:55.955Z
"
,
"updated_by"
:
"aff87dea-73a3-4076-b1be-6b0b7b59a21d
"
,
updated_by
:
"aff87dea-73a3-4076-b1be-6b0b7b59a21d
"
,
"type"
:
"news
"
,
type
:
"news
"
,
"parent_id"
:
"c66f9e44-8422-4a67-a1e5-f90e3445d87e
"
,
parent_id
:
"c66f9e44-8422-4a67-a1e5-f90e3445d87e"
,
"sort_order"
:
3
,
thumbnail
:
null
,
"thumbnail"
:
null
},
},
{
{
id
:
"5aabbe25-6440-4bcb-b50b-0328cc152741"
,
"id"
:
"5aabbe25-6440-4bcb-b50b-0328cc152741"
,
name
:
"Chức năng Đại diện Người sử dụng lao động"
,
"name"
:
"Chức năng Đại diện Người sử dụng lao động"
,
slug
:
"chuc-nang-dai-dien-nguoi-su-dung-lao-dong"
,
"slug"
:
"chuc-nang-dai-dien-nguoi-su-dung-lao-dong"
,
url
:
"/dai-dien-gioi-chu/chuc-nang-dai-dien-nguoi-su-dung-lao-dong"
,
"url"
:
"/dai-dien-gioi-chu/chuc-nang-dai-dien-nguoi-su-dung-lao-dong"
,
sort_order
:
1
,
"created_at"
:
"2026-05-14T04:54:26.127Z"
,
created_at
:
"2026-05-14T04:54:26.127Z"
,
"created_by"
:
null
,
created_by
:
null
,
"updated_at"
:
"2026-05-14T16:14:15.491Z"
,
updated_at
:
"2026-05-14T16:14:15.491Z
"
,
"updated_by"
:
"aff87dea-73a3-4076-b1be-6b0b7b59a21d
"
,
updated_by
:
"aff87dea-73a3-4076-b1be-6b0b7b59a21d
"
,
"type"
:
"page
"
,
type
:
"pag
e"
,
"parent_id"
:
"bd4f75ef-27b8-4f02-9ba8-9fc3112c7cf
e"
,
parent_id
:
"bd4f75ef-27b8-4f02-9ba8-9fc3112c7cfe"
,
"sort_order"
:
1
,
thumbnail
:
null
,
"thumbnail"
:
null
},
},
{
{
id
:
"5fdd332c-e42d-490f-964b-2db464f75630"
,
"id"
:
"5fdd332c-e42d-490f-964b-2db464f75630"
,
name
:
"Thông tin liên hệ"
,
"name"
:
"Thông tin liên hệ"
,
slug
:
"thong-tin-lien-he-co"
,
"slug"
:
"thong-tin-lien-he-co"
,
url
:
"/xuat-xu-hang-hoa/thong-tin-lien-he-co"
,
"url"
:
"/xuat-xu-hang-hoa/thong-tin-lien-he-co"
,
sort_order
:
8
,
"created_at"
:
"2026-05-14T04:54:26.127Z"
,
created_at
:
"2026-05-14T04:54:26.127Z"
,
"created_by"
:
null
,
created_by
:
null
,
"updated_at"
:
"2026-05-14T16:14:01.427Z"
,
updated_at
:
"2026-05-14T16:14:01.427Z
"
,
"updated_by"
:
"aff87dea-73a3-4076-b1be-6b0b7b59a21d
"
,
updated_by
:
"aff87dea-73a3-4076-b1be-6b0b7b59a21d
"
,
"type"
:
"page
"
,
type
:
"page
"
,
"parent_id"
:
"69b4c7e7-28ea-41f2-97f4-988fe702a8a3
"
,
parent_id
:
"69b4c7e7-28ea-41f2-97f4-988fe702a8a3"
,
"sort_order"
:
8
,
thumbnail
:
null
,
"thumbnail"
:
null
},
},
{
{
id
:
"9ddb2539-41ee-4ed3-8146-75362ac2b1be"
,
"id"
:
"9ddb2539-41ee-4ed3-8146-75362ac2b1be"
,
name
:
"Phí và Lệ phí cấp C/O"
,
"name"
:
"Phí và Lệ phí cấp C/O"
,
slug
:
"phi-va-le-phi-cap-co"
,
"slug"
:
"phi-va-le-phi-cap-co"
,
url
:
"/xuat-xu-hang-hoa/phi-va-le-phi-cap-co"
,
"url"
:
"/xuat-xu-hang-hoa/phi-va-le-phi-cap-co"
,
sort_order
:
6
,
"created_at"
:
"2026-05-14T04:54:26.127Z"
,
created_at
:
"2026-05-14T04:54:26.127Z"
,
"created_by"
:
null
,
created_by
:
null
,
"updated_at"
:
"2026-05-14T16:13:45.539Z"
,
updated_at
:
"2026-05-14T16:13:45.539Z
"
,
"updated_by"
:
"aff87dea-73a3-4076-b1be-6b0b7b59a21d
"
,
updated_by
:
"aff87dea-73a3-4076-b1be-6b0b7b59a21d
"
,
"type"
:
"page
"
,
type
:
"page
"
,
"parent_id"
:
"69b4c7e7-28ea-41f2-97f4-988fe702a8a3
"
,
parent_id
:
"69b4c7e7-28ea-41f2-97f4-988fe702a8a3"
,
"sort_order"
:
6
,
thumbnail
:
null
,
"thumbnail"
:
null
},
},
{
{
id
:
"c177a719-7f9e-443c-bdeb-0676a2f6fa6b"
,
"id"
:
"c177a719-7f9e-443c-bdeb-0676a2f6fa6b"
,
name
:
"Biểu mẫu C/O và cách khai"
,
"name"
:
"Biểu mẫu C/O và cách khai"
,
slug
:
"bieu-mau-co-va-cach-khai"
,
"slug"
:
"bieu-mau-co-va-cach-khai"
,
url
:
"/xuat-xu-hang-hoa/bieu-mau-co-va-cach-khai"
,
"url"
:
"/xuat-xu-hang-hoa/bieu-mau-co-va-cach-khai"
,
sort_order
:
5
,
"created_at"
:
"2026-05-14T04:54:26.127Z"
,
created_at
:
"2026-05-14T04:54:26.127Z"
,
"created_by"
:
null
,
created_by
:
null
,
"updated_at"
:
"2026-05-14T16:13:27.063Z"
,
updated_at
:
"2026-05-14T16:13:27.063Z
"
,
"updated_by"
:
"aff87dea-73a3-4076-b1be-6b0b7b59a21d
"
,
updated_by
:
"aff87dea-73a3-4076-b1be-6b0b7b59a21d
"
,
"type"
:
"page
"
,
type
:
"page
"
,
"parent_id"
:
"69b4c7e7-28ea-41f2-97f4-988fe702a8a3
"
,
parent_id
:
"69b4c7e7-28ea-41f2-97f4-988fe702a8a3"
,
"sort_order"
:
5
,
thumbnail
:
null
,
"thumbnail"
:
null
},
},
{
{
id
:
"531d92b1-ae11-4915-815a-c2a4bdb9952d"
,
"id"
:
"531d92b1-ae11-4915-815a-c2a4bdb9952d"
,
name
:
"Thủ tục cấp C/O"
,
"name"
:
"Thủ tục cấp C/O"
,
slug
:
"thu-tuc-cap-co"
,
"slug"
:
"thu-tuc-cap-co"
,
url
:
"/xuat-xu-hang-hoa/thu-tuc-cap-co"
,
"url"
:
"/xuat-xu-hang-hoa/thu-tuc-cap-co"
,
sort_order
:
4
,
"created_at"
:
"2026-05-14T04:54:26.127Z"
,
created_at
:
"2026-05-14T04:54:26.127Z"
,
"created_by"
:
null
,
created_by
:
null
,
"updated_at"
:
"2026-05-14T16:13:09.052Z"
,
updated_at
:
"2026-05-14T16:13:09.052Z
"
,
"updated_by"
:
"aff87dea-73a3-4076-b1be-6b0b7b59a21d
"
,
updated_by
:
"aff87dea-73a3-4076-b1be-6b0b7b59a21d
"
,
"type"
:
"page
"
,
type
:
"page
"
,
"parent_id"
:
"69b4c7e7-28ea-41f2-97f4-988fe702a8a3
"
,
parent_id
:
"69b4c7e7-28ea-41f2-97f4-988fe702a8a3"
,
"sort_order"
:
4
,
thumbnail
:
null
,
"thumbnail"
:
null
},
},
{
{
id
:
"e4540f67-ee2c-4d12-a015-0c4484276ff2"
,
"id"
:
"e4540f67-ee2c-4d12-a015-0c4484276ff2"
,
name
:
"Luật áp dụng về C/O"
,
"name"
:
"Luật áp dụng về C/O"
,
slug
:
"luat-ap-dung-ve-co"
,
"slug"
:
"luat-ap-dung-ve-co"
,
url
:
"/xuat-xu-hang-hoa/luat-ap-dung-ve-co"
,
"url"
:
"/xuat-xu-hang-hoa/luat-ap-dung-ve-co"
,
sort_order
:
3
,
"created_at"
:
"2026-05-14T04:54:26.127Z"
,
created_at
:
"2026-05-14T04:54:26.127Z"
,
"created_by"
:
null
,
created_by
:
null
,
"updated_at"
:
"2026-05-14T16:12:56.267Z"
,
updated_at
:
"2026-05-14T16:12:56.267Z
"
,
"updated_by"
:
"aff87dea-73a3-4076-b1be-6b0b7b59a21d
"
,
updated_by
:
"aff87dea-73a3-4076-b1be-6b0b7b59a21d
"
,
"type"
:
"page
"
,
type
:
"page
"
,
"parent_id"
:
"69b4c7e7-28ea-41f2-97f4-988fe702a8a3
"
,
parent_id
:
"69b4c7e7-28ea-41f2-97f4-988fe702a8a3"
,
"sort_order"
:
3
,
thumbnail
:
null
,
"thumbnail"
:
null
},
},
{
{
id
:
"8ea819ea-bedf-4357-9228-f8730c706c34"
,
"id"
:
"8ea819ea-bedf-4357-9228-f8730c706c34"
,
name
:
"Mục đích của C/O"
,
"name"
:
"Mục đích của C/O"
,
slug
:
"muc-dich-cua-co"
,
"slug"
:
"muc-dich-cua-co"
,
url
:
"/xuat-xu-hang-hoa/muc-dich-cua-co"
,
"url"
:
"/xuat-xu-hang-hoa/muc-dich-cua-co"
,
sort_order
:
2
,
"created_at"
:
"2026-05-14T04:54:26.127Z"
,
created_at
:
"2026-05-14T04:54:26.127Z"
,
"created_by"
:
null
,
created_by
:
null
,
"updated_at"
:
"2026-05-14T16:12:49.423Z"
,
updated_at
:
"2026-05-14T16:12:49.423Z
"
,
"updated_by"
:
"aff87dea-73a3-4076-b1be-6b0b7b59a21d
"
,
updated_by
:
"aff87dea-73a3-4076-b1be-6b0b7b59a21d
"
,
"type"
:
"page
"
,
type
:
"page
"
,
"parent_id"
:
"69b4c7e7-28ea-41f2-97f4-988fe702a8a3
"
,
parent_id
:
"69b4c7e7-28ea-41f2-97f4-988fe702a8a3"
,
"sort_order"
:
2
,
thumbnail
:
null
,
"thumbnail"
:
null
},
},
{
{
id
:
"23dc501f-93bb-41d7-b05e-ace02a65cfd7"
,
"id"
:
"23dc501f-93bb-41d7-b05e-ace02a65cfd7"
,
name
:
"Thông tin truyền thống"
,
"name"
:
"Thông tin truyền thống"
,
slug
:
"thong-tin-truyen-thong"
,
"slug"
:
"thong-tin-truyen-thong"
,
url
:
"/thong-tin-truyen-thong"
,
"url"
:
"/thong-tin-truyen-thong"
,
sort_order
:
8
,
"created_at"
:
"2026-05-14T04:54:26.127Z"
,
created_at
:
"2026-05-14T04:54:26.127Z"
,
"created_by"
:
null
,
created_by
:
null
,
"updated_at"
:
"2026-05-14T16:10:43.096Z"
,
updated_at
:
"2026-05-14T16:10:43.096Z
"
,
"updated_by"
:
"aff87dea-73a3-4076-b1be-6b0b7b59a21d
"
,
updated_by
:
"aff87dea-73a3-4076-b1be-6b0b7b59a21d
"
,
"type"
:
"category
"
,
type
:
"category"
,
"parent_id"
:
null
,
parent_id
:
null
,
"sort_order"
:
8
,
thumbnail
:
null
,
"thumbnail"
:
null
},
},
{
{
id
:
"bd4f75ef-27b8-4f02-9ba8-9fc3112c7cfe"
,
"id"
:
"bd4f75ef-27b8-4f02-9ba8-9fc3112c7cfe"
,
name
:
"Đại diện giới chủ"
,
"name"
:
"Đại diện giới chủ"
,
slug
:
"dai-dien-gioi-chu"
,
"slug"
:
"dai-dien-gioi-chu"
,
url
:
"/dai-dien-gioi-chu"
,
"url"
:
"/dai-dien-gioi-chu"
,
sort_order
:
6
,
"created_at"
:
"2026-05-14T04:54:26.127Z"
,
created_at
:
"2026-05-14T04:54:26.127Z"
,
"created_by"
:
null
,
created_by
:
null
,
"updated_at"
:
"2026-05-14T16:10:18.140Z"
,
updated_at
:
"2026-05-14T16:10:18.140Z
"
,
"updated_by"
:
"aff87dea-73a3-4076-b1be-6b0b7b59a21d
"
,
updated_by
:
"aff87dea-73a3-4076-b1be-6b0b7b59a21d
"
,
"type"
:
"category
"
,
type
:
"category"
,
"parent_id"
:
null
,
parent_id
:
null
,
"sort_order"
:
6
,
thumbnail
:
null
,
"thumbnail"
:
null
},
},
{
{
id
:
"142c9525-b206-4b87-8978-4b7048a46a3b
"
,
"id"
:
"f28ebc98-d897-46b9-bbf4-95a79c4d1f77
"
,
name
:
"Trang chủ
"
,
"name"
:
"Giới thiệu
"
,
slug
:
"trang-ch
u"
,
"slug"
:
"gioi-thie
u"
,
url
:
"/
"
,
"url"
:
"/gioi-thieu
"
,
sort_order
:
1
,
"created_at"
:
"2026-05-14T04:54:26.127Z"
,
created_at
:
"2026-05-14T04:54:26.127Z"
,
"created_by"
:
null
,
created_by
:
null
,
"updated_at"
:
"2026-05-14T16:09:32.656Z"
,
updated_at
:
"2026-05-14T16:08:17.773Z
"
,
"updated_by"
:
"aff87dea-73a3-4076-b1be-6b0b7b59a21d
"
,
updated_by
:
"aff87dea-73a3-4076-b1be-6b0b7b59a21d
"
,
"type"
:
"category
"
,
type
:
"page"
,
"parent_id"
:
null
,
parent_id
:
null
,
"sort_order"
:
2
,
thumbnail
:
null
,
"thumbnail"
:
null
},
},
{
{
id
:
"f28ebc98-d897-46b9-bbf4-95a79c4d1f77
"
,
"id"
:
"d6fc72a4-048e-4a88-a5d8-1fa7bd6a14f8
"
,
name
:
"Giới thiệu
"
,
"name"
:
"Chủ đề
"
,
slug
:
"gioi-thieu
"
,
"slug"
:
"chu-de
"
,
url
:
"/gioi-thieu
"
,
"url"
:
"/dai-dien-gioi-chu/chu-de
"
,
sort_order
:
2
,
"created_at"
:
"2026-05-14T04:54:26.127Z"
,
created_at
:
"2026-05-14T04:54:26.127Z"
,
"created_by"
:
null
,
created_by
:
null
,
"updated_at"
:
"2026-05-16T14:12:23.824Z"
,
updated_at
:
"2026-05-14T16:09:32.656Z
"
,
"updated_by"
:
"aff87dea-73a3-4076-b1be-6b0b7b59a21d
"
,
updated_by
:
"aff87dea-73a3-4076-b1be-6b0b7b59a21d
"
,
"type"
:
"news
"
,
type
:
"category
"
,
"parent_id"
:
"bd4f75ef-27b8-4f02-9ba8-9fc3112c7cfe
"
,
parent_id
:
null
,
"sort_order"
:
4
,
thumbnail
:
null
,
"thumbnail"
:
null
},
},
{
{
id
:
"755106b6-1aca-47dc-9a9c-d434736c33a1
"
,
"id"
:
"69b4c7e7-28ea-41f2-97f4-988fe702a8a3
"
,
name
:
"Tin Kinh tế
"
,
"name"
:
"Pháp chế, cấp giấy chứng nhận và xác nhận chứng từ thương mại
"
,
slug
:
"tin-kinh-te
"
,
"slug"
:
"phap-che-cap-giay-chung-nhan-va-xac-nhan-chung-tu-thuong-mai
"
,
url
:
"/thong-tin-truyen-thong/tin-kinh-te
"
,
"url"
:
"/phap-che-cap-giay-chung-nhan-va-xac-nhan-chung-tu-thuong-mai
"
,
sort_order
:
2
,
"created_at"
:
"2026-05-14T04:54:26.127Z"
,
created_at
:
"2026-05-14T04:54:26.127Z"
,
"created_by"
:
null
,
created_by
:
null
,
"updated_at"
:
"2026-05-15T08:29:25.863Z"
,
updated_at
:
"2026-05-14T16:16:04.817Z
"
,
"updated_by"
:
"aff87dea-73a3-4076-b1be-6b0b7b59a21d
"
,
updated_by
:
"aff87dea-73a3-4076-b1be-6b0b7b59a21d
"
,
"type"
:
"category
"
,
type
:
"news"
,
"parent_id"
:
null
,
parent_id
:
"23dc501f-93bb-41d7-b05e-ace02a65cfd7"
,
"sort_order"
:
5
,
thumbnail
:
null
,
"thumbnail"
:
null
},
},
{
{
id
:
"605a2eb4-bd60-4469-891c-d809ec46b5b5
"
,
"id"
:
"142c9525-b206-4b87-8978-4b7048a46a3b
"
,
name
:
"Thư viện tài liệu
"
,
"name"
:
"Trang chủ
"
,
slug
:
"thu-vien-tai-lie
u"
,
"slug"
:
"trang-ch
u"
,
url
:
"/thong-tin-truyen-thong/thu-vien-tai-lie
u"
,
"url"
:
"/trang-ch
u"
,
sort_order
:
7
,
"created_at"
:
"2026-05-14T04:54:26.127Z"
,
created_at
:
"2026-05-14T04:54:26.127Z"
,
"created_by"
:
null
,
created_by
:
null
,
"updated_at"
:
"2026-05-14T19:19:14.819Z"
,
updated_at
:
"2026-05-14T16:18:01.028Z
"
,
"updated_by"
:
"aff87dea-73a3-4076-b1be-6b0b7b59a21d
"
,
updated_by
:
"aff87dea-73a3-4076-b1be-6b0b7b59a21d
"
,
"type"
:
"page
"
,
type
:
"news"
,
"parent_id"
:
null
,
parent_id
:
"23dc501f-93bb-41d7-b05e-ace02a65cfd7"
,
"sort_order"
:
1
,
thumbnail
:
null
,
"thumbnail"
:
null
},
},
{
{
id
:
"90bfdd91-a7d5-4d55-908b-84e512c36b70
"
,
"id"
:
"605a2eb4-bd60-4469-891c-d809ec46b5b5
"
,
name
:
"Về VCCI-HCM
"
,
"name"
:
"Thư viện tài liệu
"
,
slug
:
"ve-vcci-hcm
"
,
"slug"
:
"thu-vien-tai-lieu
"
,
url
:
"/gioi-thieu/ve-vcci-hcm
"
,
"url"
:
"/thong-tin-truyen-thong/thu-vien-tai-lieu
"
,
sort_order
:
1
,
"created_at"
:
"2026-05-14T04:54:26.127Z"
,
created_at
:
"2026-05-14T04:54:26.127Z"
,
"created_by"
:
null
,
created_by
:
null
,
"updated_at"
:
"2026-05-14T16:18:01.028Z"
,
updated_at
:
"2026-05-14T16:11:00.836Z
"
,
"updated_by"
:
"aff87dea-73a3-4076-b1be-6b0b7b59a21d
"
,
updated_by
:
"aff87dea-73a3-4076-b1be-6b0b7b59a21d
"
,
"type"
:
"news
"
,
type
:
"page
"
,
"parent_id"
:
"23dc501f-93bb-41d7-b05e-ace02a65cfd7
"
,
parent_id
:
"f28ebc98-d897-46b9-bbf4-95a79c4d1f77"
,
"sort_order"
:
7
,
thumbnail
:
null
,
"thumbnail"
:
null
},
},
{
{
id
:
"b85f6710-bcbc-4c0b-8b3a-09fff0e5e51a
"
,
"id"
:
"90bfdd91-a7d5-4d55-908b-84e512c36b70
"
,
name
:
"Sự kiện
"
,
"name"
:
"Về VCCI-HCM
"
,
slug
:
"su-kien
"
,
"slug"
:
"ve-vcci-hcm
"
,
url
:
"/hoat-dong/su-kien
"
,
"url"
:
"/gioi-thieu/ve-vcci-hcm
"
,
sort_order
:
1
,
"created_at"
:
"2026-05-14T04:54:26.127Z"
,
created_at
:
"2026-05-14T04:54:26.127Z"
,
"created_by"
:
null
,
created_by
:
null
,
"updated_at"
:
"2026-05-14T16:11:00.836Z"
,
updated_at
:
"2026-05-14T16:12:19.157Z
"
,
"updated_by"
:
"aff87dea-73a3-4076-b1be-6b0b7b59a21d
"
,
updated_by
:
"aff87dea-73a3-4076-b1be-6b0b7b59a21d
"
,
"type"
:
"page
"
,
type
:
"news
"
,
"parent_id"
:
"f28ebc98-d897-46b9-bbf4-95a79c4d1f77
"
,
parent_id
:
"fb53905e-999b-4f54-a5f1-98c94ba03d62"
,
"sort_order"
:
1
,
thumbnail
:
null
,
"thumbnail"
:
null
},
},
{
{
id
:
"b1d5ac97-fe08-4b38-93ff-dc4c9f1a8f28
"
,
"id"
:
"b85f6710-bcbc-4c0b-8b3a-09fff0e5e51a
"
,
name
:
"Đăng ký hội viê
n"
,
"name"
:
"Sự kiệ
n"
,
slug
:
"dang-ky-hoi-v
ien"
,
"slug"
:
"su-k
ien"
,
url
:
"/hoi-vien/dang-ky-hoi-v
ien"
,
"url"
:
"/hoat-dong/su-k
ien"
,
sort_order
:
2
,
"created_at"
:
"2026-05-14T04:54:26.127Z"
,
created_at
:
"2026-05-14T04:54:26.127Z"
,
"created_by"
:
null
,
created_by
:
null
,
"updated_at"
:
"2026-05-14T16:12:19.157Z"
,
updated_at
:
"2026-05-14T16:11:53.287Z
"
,
"updated_by"
:
"aff87dea-73a3-4076-b1be-6b0b7b59a21d
"
,
updated_by
:
"aff87dea-73a3-4076-b1be-6b0b7b59a21d
"
,
"type"
:
"news
"
,
type
:
"page
"
,
"parent_id"
:
"fb53905e-999b-4f54-a5f1-98c94ba03d62
"
,
parent_id
:
"3c92b2d5-1fa8-412b-bf3b-49b779f1a1c1"
,
"sort_order"
:
1
,
thumbnail
:
null
,
"thumbnail"
:
null
},
},
{
{
id
:
"497eed1b-22f1-4be8-a737-cdc40b992f0e
"
,
"id"
:
"b1d5ac97-fe08-4b38-93ff-dc4c9f1a8f28
"
,
name
:
"Tin H
ội viên"
,
"name"
:
"Đăng ký h
ội viên"
,
slug
:
"tin
-hoi-vien"
,
"slug"
:
"dang-ky
-hoi-vien"
,
url
:
"/hoi-vien/tin
-hoi-vien"
,
"url"
:
"/hoi-vien/dang-ky
-hoi-vien"
,
sort_order
:
4
,
"created_at"
:
"2026-05-14T04:54:26.127Z"
,
created_at
:
"2026-05-14T04:54:26.127Z"
,
"created_by"
:
null
,
created_by
:
null
,
"updated_at"
:
"2026-05-14T16:11:53.287Z"
,
updated_at
:
"2026-05-14T16:12:04.430Z
"
,
"updated_by"
:
"aff87dea-73a3-4076-b1be-6b0b7b59a21d
"
,
updated_by
:
"aff87dea-73a3-4076-b1be-6b0b7b59a21d
"
,
"type"
:
"page
"
,
type
:
"news
"
,
"parent_id"
:
"3c92b2d5-1fa8-412b-bf3b-49b779f1a1c1
"
,
parent_id
:
"3c92b2d5-1fa8-412b-bf3b-49b779f1a1c1"
,
"sort_order"
:
2
,
thumbnail
:
null
,
"thumbnail"
:
null
},
},
{
{
id
:
"a37b8a02-e8b3-42ce-9225-6dae460fed99
"
,
"id"
:
"497eed1b-22f1-4be8-a737-cdc40b992f0e
"
,
name
:
"Kết nối h
ội viên"
,
"name"
:
"Tin H
ội viên"
,
slug
:
"ket-noi
-hoi-vien"
,
"slug"
:
"tin
-hoi-vien"
,
url
:
"/hoi-vien/ket-noi
-hoi-vien"
,
"url"
:
"/hoi-vien/tin
-hoi-vien"
,
sort_order
:
3
,
"created_at"
:
"2026-05-14T04:54:26.127Z"
,
created_at
:
"2026-05-14T04:54:26.127Z"
,
"created_by"
:
null
,
created_by
:
null
,
"updated_at"
:
"2026-05-14T16:12:04.430Z"
,
updated_at
:
"2026-05-14T16:11:58.465Z
"
,
"updated_by"
:
"aff87dea-73a3-4076-b1be-6b0b7b59a21d
"
,
updated_by
:
"aff87dea-73a3-4076-b1be-6b0b7b59a21d
"
,
"type"
:
"news
"
,
type
:
"page
"
,
"parent_id"
:
"3c92b2d5-1fa8-412b-bf3b-49b779f1a1c1
"
,
parent_id
:
"3c92b2d5-1fa8-412b-bf3b-49b779f1a1c1"
,
"sort_order"
:
4
,
thumbnail
:
null
,
"thumbnail"
:
null
},
},
{
{
id
:
"fb53905e-999b-4f54-a5f1-98c94ba03d62
"
,
"id"
:
"a37b8a02-e8b3-42ce-9225-6dae460fed99
"
,
name
:
"Hoạt động
"
,
"name"
:
"Kết nối hội viên
"
,
slug
:
"hoat-dong
"
,
"slug"
:
"ket-noi-hoi-vien
"
,
url
:
"/hoat-dong
"
,
"url"
:
"/hoi-vien/ket-noi-hoi-vien
"
,
sort_order
:
4
,
"created_at"
:
"2026-05-14T04:54:26.127Z"
,
created_at
:
"2026-05-14T04:54:26.127Z"
,
"created_by"
:
null
,
created_by
:
null
,
"updated_at"
:
"2026-05-14T16:11:58.465Z"
,
updated_at
:
"2026-05-14T16:09:59.200Z
"
,
"updated_by"
:
"aff87dea-73a3-4076-b1be-6b0b7b59a21d
"
,
updated_by
:
"aff87dea-73a3-4076-b1be-6b0b7b59a21d
"
,
"type"
:
"page
"
,
type
:
"category
"
,
"parent_id"
:
"3c92b2d5-1fa8-412b-bf3b-49b779f1a1c1
"
,
parent_id
:
null
,
"sort_order"
:
3
,
thumbnail
:
null
,
"thumbnail"
:
null
},
},
{
{
id
:
"36df7021-9a74-43d6-9084-0d5ed347b7f4
"
,
"id"
:
"fb53905e-999b-4f54-a5f1-98c94ba03d62
"
,
name
:
"Hoạt động"
,
"name"
:
"Hoạt động"
,
slug
:
"tin-
hoat-dong"
,
"slug"
:
"
hoat-dong"
,
url
:
"/hoat-dong/tin-
hoat-dong"
,
"url"
:
"/
hoat-dong"
,
sort_order
:
2
,
"created_at"
:
"2026-05-14T04:54:26.127Z"
,
created_at
:
"2026-05-14T04:54:26.127Z"
,
"created_by"
:
null
,
created_by
:
null
,
"updated_at"
:
"2026-05-14T16:09:59.200Z"
,
updated_at
:
"2026-05-14T16:12:24.773Z
"
,
"updated_by"
:
"aff87dea-73a3-4076-b1be-6b0b7b59a21d
"
,
updated_by
:
"aff87dea-73a3-4076-b1be-6b0b7b59a21d
"
,
"type"
:
"category
"
,
type
:
"news"
,
"parent_id"
:
null
,
parent_id
:
"fb53905e-999b-4f54-a5f1-98c94ba03d62"
,
"sort_order"
:
4
,
thumbnail
:
null
,
"thumbnail"
:
null
},
},
{
{
id
:
"521f4270-0836-4c18-b81f-9c25e7822c0a"
,
"id"
:
"521f4270-0836-4c18-b81f-9c25e7822c0a"
,
name
:
"Xuất xứ hàng hóa (C/O)"
,
"name"
:
"Xuất xứ hàng hóa (C/O)"
,
slug
:
"xuat-xu-hang-hoa-co"
,
"slug"
:
"xuat-xu-hang-hoa-co"
,
url
:
"/xuat-xu-hang-hoa/xuat-xu-hang-hoa-co"
,
"url"
:
"/xuat-xu-hang-hoa/xuat-xu-hang-hoa-co"
,
sort_order
:
1
,
"created_at"
:
"2026-05-14T04:54:26.127Z"
,
created_at
:
"2026-05-14T04:54:26.127Z"
,
"created_by"
:
null
,
created_by
:
null
,
"updated_at"
:
"2026-05-14T16:12:40.839Z"
,
updated_at
:
"2026-05-14T16:12:40.839Z
"
,
"updated_by"
:
"aff87dea-73a3-4076-b1be-6b0b7b59a21d
"
,
updated_by
:
"aff87dea-73a3-4076-b1be-6b0b7b59a21d
"
,
"type"
:
"page
"
,
type
:
"page
"
,
"parent_id"
:
"69b4c7e7-28ea-41f2-97f4-988fe702a8a3
"
,
parent_id
:
"69b4c7e7-28ea-41f2-97f4-988fe702a8a3"
,
"sort_order"
:
1
,
thumbnail
:
null
,
"thumbnail"
:
null
},
},
{
{
id
:
"69b4c7e7-28ea-41f2-97f4-988fe702a8a3
"
,
"id"
:
"90305ea7-2048-4152-8d58-ce5d1fbdf07a
"
,
name
:
"Xuất xứ hàng hóa
"
,
"name"
:
"Môi trường kinh doanh
"
,
slug
:
"xuat-xu-hang-hoa
"
,
"slug"
:
"moi-truong-kinh-doanh
"
,
url
:
"/xuat-xu-hang-hoa
"
,
"url"
:
"/xuc-tien-thuong-mai/moi-truong-kinh-doanh
"
,
sort_order
:
5
,
"created_at"
:
"2026-05-14T04:54:26.127Z"
,
created_at
:
"2026-05-14T04:54:26.127Z"
,
"created_by"
:
null
,
created_by
:
null
,
"updated_at"
:
"2026-05-16T14:12:23.945Z"
,
updated_at
:
"2026-05-14T16:10:08.136Z
"
,
"updated_by"
:
"aff87dea-73a3-4076-b1be-6b0b7b59a21d
"
,
updated_by
:
"aff87dea-73a3-4076-b1be-6b0b7b59a21d
"
,
"type"
:
"news
"
,
type
:
"category
"
,
"parent_id"
:
"c66f9e44-8422-4a67-a1e5-f90e3445d87e
"
,
parent_id
:
null
,
"sort_order"
:
2
,
thumbnail
:
null
,
"thumbnail"
:
null
},
},
{
{
id
:
"d6fc72a4-048e-4a88-a5d8-1fa7bd6a14f8
"
,
"id"
:
"c7a0b0d7-4321-4dad-ae05-794ca9f8d5fe
"
,
name
:
"Chủ đề
"
,
"name"
:
"Sự kiện – Tập huấn NSDLĐ
"
,
slug
:
"chu-de
"
,
"slug"
:
"su-kien-tap-huan-nsdld
"
,
url
:
"/dai-dien-gioi-chu/chu-de
"
,
"url"
:
"/dai-dien-gioi-chu/su-kien-tap-huan-nsdld
"
,
sort_order
:
4
,
"created_at"
:
"2026-05-14T04:54:26.127Z"
,
created_at
:
"2026-05-14T04:54:26.127Z"
,
"created_by"
:
null
,
created_by
:
null
,
"updated_at"
:
"2026-05-14T16:14:24.158Z"
,
updated_at
:
"2026-05-14T16:14:36.235Z
"
,
"updated_by"
:
"aff87dea-73a3-4076-b1be-6b0b7b59a21d
"
,
updated_by
:
"aff87dea-73a3-4076-b1be-6b0b7b59a21d
"
,
"type"
:
"news
"
,
type
:
"news
"
,
"parent_id"
:
"bd4f75ef-27b8-4f02-9ba8-9fc3112c7cfe
"
,
parent_id
:
"bd4f75ef-27b8-4f02-9ba8-9fc3112c7cfe"
,
"sort_order"
:
2
,
thumbnail
:
null
,
"thumbnail"
:
null
},
},
{
{
id
:
"c7a0b0d7-4321-4dad-ae05-794ca9f8d5f
e"
,
"id"
:
"be37f5ad-d87d-46db-bc24-d9ce20ae12d
e"
,
name
:
"Sự kiện – Tập huấn NSDLĐ
"
,
"name"
:
"Tin liên quan
"
,
slug
:
"su-kien-tap-huan-nsdld
"
,
"slug"
:
"tin-lien-quan
"
,
url
:
"/dai-dien-gioi-chu/su-kien-tap-huan-nsdld
"
,
"url"
:
"/dai-dien-gioi-chu/tin-lien-quan
"
,
sort_order
:
2
,
"created_at"
:
"2026-05-14T04:54:26.127Z"
,
created_at
:
"2026-05-14T04:54:26.127Z"
,
"created_by"
:
null
,
created_by
:
null
,
"updated_at"
:
"2026-05-14T16:14:29.874Z"
,
updated_at
:
"2026-05-14T16:14:24.158Z
"
,
"updated_by"
:
"aff87dea-73a3-4076-b1be-6b0b7b59a21d
"
,
updated_by
:
"aff87dea-73a3-4076-b1be-6b0b7b59a21d
"
,
"type"
:
"news
"
,
type
:
"news
"
,
"parent_id"
:
"bd4f75ef-27b8-4f02-9ba8-9fc3112c7cfe
"
,
parent_id
:
"bd4f75ef-27b8-4f02-9ba8-9fc3112c7cfe"
,
"sort_order"
:
3
,
thumbnail
:
null
,
"thumbnail"
:
null
},
},
{
{
id
:
"be37f5ad-d87d-46db-bc24-d9ce20ae12de
"
,
"id"
:
"d759b40c-1de4-4abe-8ec6-1e0df19916fc
"
,
name
:
"Tin liên quan
"
,
"name"
:
"Hồ sơ thị trường
"
,
slug
:
"tin-lien-quan
"
,
"slug"
:
"ho-so-thi-truong
"
,
url
:
"/dai-dien-gioi-chu/tin-lien-quan
"
,
"url"
:
"/xuc-tien-thuong-mai/ho-so-thi-truong
"
,
sort_order
:
3
,
"created_at"
:
"2026-05-14T04:54:26.127Z"
,
created_at
:
"2026-05-14T04:54:26.127Z"
,
"created_by"
:
null
,
created_by
:
null
,
"updated_at"
:
"2026-05-14T16:14:50.302Z"
,
updated_at
:
"2026-05-14T16:14:29.874Z
"
,
"updated_by"
:
"aff87dea-73a3-4076-b1be-6b0b7b59a21d
"
,
updated_by
:
"aff87dea-73a3-4076-b1be-6b0b7b59a21d
"
,
"type"
:
"page
"
,
type
:
"news
"
,
"parent_id"
:
"c66f9e44-8422-4a67-a1e5-f90e3445d87e
"
,
parent_id
:
"bd4f75ef-27b8-4f02-9ba8-9fc3112c7cfe"
,
"sort_order"
:
1
,
thumbnail
:
null
,
"thumbnail"
:
null
},
},
{
{
id
:
"d759b40c-1de4-4abe-8ec6-1e0df19916fc
"
,
"id"
:
"c66f9e44-8422-4a67-a1e5-f90e3445d87e
"
,
name
:
"Hồ sơ thị trường
"
,
"name"
:
"Xúc tiến thương mại
"
,
slug
:
"ho-so-thi-truong
"
,
"slug"
:
"xuc-tien-thuong-mai
"
,
url
:
"/xuc-tien-thuong-mai/ho-so-thi-truong
"
,
"url"
:
"/xuc-tien-thuong-mai
"
,
sort_order
:
1
,
"created_at"
:
"2026-05-14T04:54:26.127Z"
,
created_at
:
"2026-05-14T04:54:26.127Z"
,
"created_by"
:
null
,
created_by
:
null
,
"updated_at"
:
"2026-05-14T16:10:29.416Z"
,
updated_at
:
"2026-05-14T16:14:50.302Z
"
,
"updated_by"
:
"aff87dea-73a3-4076-b1be-6b0b7b59a21d
"
,
updated_by
:
"aff87dea-73a3-4076-b1be-6b0b7b59a21d
"
,
"type"
:
"category
"
,
type
:
"page"
,
"parent_id"
:
null
,
parent_id
:
"c66f9e44-8422-4a67-a1e5-f90e3445d87e"
,
"sort_order"
:
7
,
thumbnail
:
null
,
"thumbnail"
:
null
},
},
{
{
id
:
"c66f9e44-8422-4a67-a1e5-f90e3445d87e
"
,
"id"
:
"f7d637a7-61f4-4a12-8dd8-bb2d32494b4c
"
,
name
:
"Xúc tiến thương mại
"
,
"name"
:
"Chức năng và Nhiệm vụ
"
,
slug
:
"xuc-tien-thuong-mai
"
,
"slug"
:
"chuc-nang-va-nhiem-vu
"
,
url
:
"/xuc-tien-thuong-mai
"
,
"url"
:
"/gioi-thieu/chuc-nang-va-nhiem-vu
"
,
sort_order
:
7
,
"created_at"
:
"2026-05-14T04:54:26.127Z"
,
created_at
:
"2026-05-14T04:54:26.127Z"
,
"created_by"
:
null
,
created_by
:
null
,
"updated_at"
:
"2026-05-14T16:11:16.713Z"
,
updated_at
:
"2026-05-14T16:10:29.416Z
"
,
"updated_by"
:
"aff87dea-73a3-4076-b1be-6b0b7b59a21d
"
,
updated_by
:
"aff87dea-73a3-4076-b1be-6b0b7b59a21d
"
,
"type"
:
"page
"
,
type
:
"category
"
,
"parent_id"
:
"f28ebc98-d897-46b9-bbf4-95a79c4d1f77
"
,
parent_id
:
null
,
"sort_order"
:
2
,
thumbnail
:
null
,
"thumbnail"
:
null
},
},
{
{
id
:
"f7d637a7-61f4-4a12-8dd8-bb2d32494b4c
"
,
"id"
:
"0c2515a8-6b31-4090-af16-d45dc7f2ec00
"
,
name
:
"Chức năng và Nhiệm vụ
"
,
"name"
:
"Dịch vụ cung cấp
"
,
slug
:
"chuc-nang-va-nhiem-vu
"
,
"slug"
:
"dich-vu-cung-cap
"
,
url
:
"/gioi-thieu/chuc-nang-va-nhiem-vu
"
,
"url"
:
"/gioi-thieu/dich-vu-cung-cap
"
,
sort_order
:
2
,
"created_at"
:
"2026-05-14T04:54:26.127Z"
,
created_at
:
"2026-05-14T04:54:26.127Z"
,
"created_by"
:
null
,
created_by
:
null
,
"updated_at"
:
"2026-05-14T16:11:27.527Z"
,
updated_at
:
"2026-05-14T16:11:16.713Z
"
,
"updated_by"
:
"aff87dea-73a3-4076-b1be-6b0b7b59a21d
"
,
updated_by
:
"aff87dea-73a3-4076-b1be-6b0b7b59a21d
"
,
"type"
:
"page
"
,
type
:
"page
"
,
"parent_id"
:
"f28ebc98-d897-46b9-bbf4-95a79c4d1f77
"
,
parent_id
:
"f28ebc98-d897-46b9-bbf4-95a79c4d1f77"
,
"sort_order"
:
4
,
thumbnail
:
null
,
"thumbnail"
:
null
},
},
{
{
id
:
"0c2515a8-6b31-4090-af16-d45dc7f2ec00
"
,
"id"
:
"b2997614-df2d-42f3-9a72-904e6265c56a
"
,
name
:
"Dịch vụ cung cấp
"
,
"name"
:
"Sơ đồ Tổ chức
"
,
slug
:
"dich-vu-cung-cap
"
,
"slug"
:
"so-do-to-chuc
"
,
url
:
"/gioi-thieu/dich-vu-cung-cap
"
,
"url"
:
"/gioi-thieu/so-do-to-chuc
"
,
sort_order
:
4
,
"created_at"
:
"2026-05-14T04:54:26.127Z"
,
created_at
:
"2026-05-14T04:54:26.127Z"
,
"created_by"
:
null
,
created_by
:
null
,
"updated_at"
:
"2026-05-14T16:11:21.648Z"
,
updated_at
:
"2026-05-14T16:11:27.527Z
"
,
"updated_by"
:
"aff87dea-73a3-4076-b1be-6b0b7b59a21d
"
,
updated_by
:
"aff87dea-73a3-4076-b1be-6b0b7b59a21d
"
,
"type"
:
"page
"
,
type
:
"page
"
,
"parent_id"
:
"f28ebc98-d897-46b9-bbf4-95a79c4d1f77
"
,
parent_id
:
"f28ebc98-d897-46b9-bbf4-95a79c4d1f77"
,
"sort_order"
:
3
,
thumbnail
:
null
,
"thumbnail"
:
null
},
},
{
{
id
:
"b2997614-df2d-42f3-9a72-904e6265c56a
"
,
"id"
:
"3c92b2d5-1fa8-412b-bf3b-49b779f1a1c1
"
,
name
:
"Sơ đồ Tổ chức
"
,
"name"
:
"Hội viên
"
,
slug
:
"so-do-to-chuc
"
,
"slug"
:
"hoi-vien
"
,
url
:
"/gioi-thieu/so-do-to-chuc
"
,
"url"
:
"/hoi-vien
"
,
sort_order
:
3
,
"created_at"
:
"2026-05-14T04:54:26.127Z"
,
created_at
:
"2026-05-14T04:54:26.127Z"
,
"created_by"
:
null
,
created_by
:
null
,
"updated_at"
:
"2026-05-14T16:09:51.604Z"
,
updated_at
:
"2026-05-14T16:11:21.648Z
"
,
"updated_by"
:
"aff87dea-73a3-4076-b1be-6b0b7b59a21d
"
,
updated_by
:
"aff87dea-73a3-4076-b1be-6b0b7b59a21d
"
,
"type"
:
"category
"
,
type
:
"page"
,
"parent_id"
:
null
,
parent_id
:
"f28ebc98-d897-46b9-bbf4-95a79c4d1f77"
,
"sort_order"
:
3
,
thumbnail
:
null
,
"thumbnail"
:
null
},
},
{
{
id
:
"3c92b2d5-1fa8-412b-bf3b-49b779f1a1c1
"
,
"id"
:
"366c20ac-036a-48d0-b7b6-113156bdae40
"
,
name
:
"Hội viên
"
,
"name"
:
"Lợi ích của Hội viên VCCI
"
,
slug
:
"hoi-vien
"
,
"slug"
:
"loi-ich-hoi-vien-vcci
"
,
url
:
"/hoi-vien
"
,
"url"
:
"/hoi-vien/loi-ich-hoi-vien-vcci
"
,
sort_order
:
3
,
"created_at"
:
"2026-05-14T04:54:26.127Z"
,
created_at
:
"2026-05-14T04:54:26.127Z"
,
"created_by"
:
null
,
created_by
:
null
,
"updated_at"
:
"2026-05-14T16:11:44.605Z"
,
updated_at
:
"2026-05-14T16:09:51.604Z
"
,
"updated_by"
:
"aff87dea-73a3-4076-b1be-6b0b7b59a21d
"
,
updated_by
:
"aff87dea-73a3-4076-b1be-6b0b7b59a21d
"
,
"type"
:
"page
"
,
type
:
"category
"
,
"parent_id"
:
"3c92b2d5-1fa8-412b-bf3b-49b779f1a1c1
"
,
parent_id
:
null
,
"sort_order"
:
1
,
thumbnail
:
null
,
"thumbnail"
:
null
},
},
{
{
id
:
"366c20ac-036a-48d0-b7b6-113156bdae40
"
,
"id"
:
"36df7021-9a74-43d6-9084-0d5ed347b7f4
"
,
name
:
"Lợi ích của Hội viên VCCI
"
,
"name"
:
"Đào tạo
"
,
slug
:
"loi-ich-hoi-vien-vcci
"
,
"slug"
:
"dao-tao
"
,
url
:
"/hoi-vien/loi-ich-hoi-vien-vcci
"
,
"url"
:
"/hoat-dong/dao-tao
"
,
sort_order
:
1
,
"created_at"
:
"2026-05-14T04:54:26.127Z"
,
created_at
:
"2026-05-14T04:54:26.127Z"
,
"created_by"
:
null
,
created_by
:
null
,
"updated_at"
:
"2026-05-15T10:15:39.460Z"
,
updated_at
:
"2026-05-14T16:11:44.605Z
"
,
"updated_by"
:
"aff87dea-73a3-4076-b1be-6b0b7b59a21d
"
,
updated_by
:
"aff87dea-73a3-4076-b1be-6b0b7b59a21d
"
,
"type"
:
"news
"
,
type
:
"page
"
,
"parent_id"
:
"fb53905e-999b-4f54-a5f1-98c94ba03d62
"
,
parent_id
:
"3c92b2d5-1fa8-412b-bf3b-49b779f1a1c1"
,
"sort_order"
:
2
,
thumbnail
:
null
,
"thumbnail"
:
null
},
},
];
];
...
...
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