Commit 67165167 authored by Lê Bảo Hồng Đức's avatar Lê Bảo Hồng Đức

fix

parent e18f1e9a
'use client'; 'use client';
import dayjs from "dayjs";
import ListCategory from "@/components/base/list-category"; import ListCategory from "@/components/base/list-category";
import { buildDynamicCategoryMenu } from "./data"; import { buildDynamicCategoryMenu } from "./data";
import StructuredPostContent from "./StructuredPostContent";
import type { DynamicCategoryRouteItem, DynamicPostItem } from "./types"; import type { DynamicCategoryRouteItem, DynamicPostItem } from "./types";
import {
ABOUT_VCCI_HCM_SLUG,
AboutVcciHcmPage,
DefaultInformationPage,
LEGAL_TRADE_PAGE_SLUG,
LegalTradePages,
MARKET_PROFILE_PAGE_SLUG,
MarketProfilePage,
MEMBER_REGISTRATION_PAGE_SLUG,
MEMBER_BENEFITS_PAGE_SLUG,
MemberRegistrationPage,
MemberBenefitsPage,
SERVICE_PAGE_SLUG,
ServicePage,
} from "./information-pages";
type InformationPageProps = { type InformationPageProps = {
post: DynamicPostItem; post: DynamicPostItem;
...@@ -12,44 +25,118 @@ type InformationPageProps = { ...@@ -12,44 +25,118 @@ type InformationPageProps = {
allCategories: DynamicCategoryRouteItem[]; allCategories: DynamicCategoryRouteItem[];
}; };
const LEGAL_TRADE_CATEGORY_ID = "69b4c7e7-28ea-41f2-97f4-988fe702a8a3";
const LEGAL_TRADE_CHILD_SLUGS = new Set([
"xuat-xu-hang-hoa-co",
"thu-tuc-cap-co",
"bieu-mau-co-va-cach-khai",
"phi-va-le-phi-cap-co",
"diem-cap-va-thoi-gian-cap-co",
"thong-tin-lien-he-co",
]);
function resolveInformationVariant(post: DynamicPostItem, category: DynamicCategoryRouteItem) {
if (
category.slug === ABOUT_VCCI_HCM_SLUG ||
post.slug === ABOUT_VCCI_HCM_SLUG ||
post.categories.some((item) => item.url === "/gioi-thieu/ve-vcci-hcm")
) {
return "about-vcci-hcm" as const;
}
if (
category.slug === SERVICE_PAGE_SLUG ||
post.slug === SERVICE_PAGE_SLUG ||
post.categories.some((item) => item.url === "/gioi-thieu/dich-vu-cung-cap")
) {
return "service" as const;
}
if (
category.slug === MEMBER_BENEFITS_PAGE_SLUG ||
post.slug === MEMBER_BENEFITS_PAGE_SLUG ||
post.categories.some((item) => item.url === "/hoi-vien/loi-ich-hoi-vien-vcci")
) {
return "member-benefits" as const;
}
if (
category.slug === MEMBER_REGISTRATION_PAGE_SLUG ||
post.slug === MEMBER_REGISTRATION_PAGE_SLUG ||
post.categories.some((item) => item.url === "/hoi-vien/dang-ky-hoi-vien")
) {
return "member-registration" as const;
}
if (
category.slug === MARKET_PROFILE_PAGE_SLUG ||
post.slug === MARKET_PROFILE_PAGE_SLUG ||
post.categories.some((item) => item.url === "/xuc-tien-thuong-mai/ho-so-thi-truong")
) {
return "market-profile" as const;
}
if (
category.slug === LEGAL_TRADE_PAGE_SLUG ||
category.parent_id === LEGAL_TRADE_CATEGORY_ID ||
LEGAL_TRADE_CHILD_SLUGS.has(category.slug) ||
post.slug === LEGAL_TRADE_PAGE_SLUG ||
LEGAL_TRADE_CHILD_SLUGS.has(post.slug) ||
post.categories.some((item) => item.id === LEGAL_TRADE_CATEGORY_ID) ||
post.categories.some(
(item) =>
item.url === "/phap-che-cap-giay-chung-nhan-va-xac-nhan-chung-tu-thuong-mai" ||
item.url.startsWith("/xuat-xu-hang-hoa/"),
)
) {
return "legal-trade" as const;
}
return "default" as const;
}
function hasRenderablePostData(post: DynamicPostItem) {
if (post.content.trim()) return true;
const sections = post.content_structure?.post_content ?? [];
return sections.some((section) => section.content.trim() || section.images.length > 0);
}
export default function InformationPage({ export default function InformationPage({
post, post,
category, category,
allCategories, allCategories,
}: InformationPageProps) { }: InformationPageProps) {
const publishedDate = dayjs(
post.release_at ?? post.published_at ?? post.created_at,
).format("DD/MM/YYYY");
const categoryMenu = buildDynamicCategoryMenu(category, allCategories); const categoryMenu = buildDynamicCategoryMenu(category, allCategories);
const variant = resolveInformationVariant(post, category);
const useSpecialUi =
variant === "about-vcci-hcm" ||
(variant !== "default" && !hasRenderablePostData(post));
return ( return (
<div className="min-h-screen bg-white"> <div className="min-h-screen bg-white">
{categoryMenu.length ? <ListCategory categories={categoryMenu} /> : null} {categoryMenu.length ? <ListCategory categories={categoryMenu} /> : null}
<div className="container mx-auto px-4 py-4 lg:pb-6 sm:px-6 lg:px-10"> <div className="container mx-auto px-4 py-4 sm:px-6 lg:px-10 lg:pb-6">
<main className="w-full"> <main className="w-full">
{/* <div className="mb-5 flex flex-wrap items-center gap-3 text-xs"> {useSpecialUi ? (
<span className="rounded-full bg-[#eaf0ff] px-2.5 py-1 font-semibold text-[#1f4fa3]"> variant === "about-vcci-hcm" ? (
{category.name} <AboutVcciHcmPage post={post} />
</span> ) : variant === "service" ? (
<span className="text-[#9aa3ad]">{publishedDate}</span> <ServicePage post={post} />
</div> */} ) : variant === "member-benefits" ? (
<MemberBenefitsPage />
<h1 className="max-w-6xl text-3xl font-bold leading-tight text-[#111827] md:text-[38px] md:leading-[1.15]"> ) : variant === "member-registration" ? (
{post.title} <MemberRegistrationPage post={post} />
</h1> ) : variant === "market-profile" ? (
<div className="mt-3 h-[3px] w-16 rounded-full bg-[#f5a400]" /> <MarketProfilePage post={post} />
) : variant === "legal-trade" ? (
{post.summary ? ( <LegalTradePages post={post} category={category} />
<p className="mt-5 max-w-6xl text-base font-semibold leading-7 text-[#374151] md:text-lg md:leading-8"> ) : (
{post.summary} <DefaultInformationPage post={post} />
</p> )
) : null} ) : (
<DefaultInformationPage post={post} />
<div className="mt-7 rounded-3xl bg-white px-5 py-6 shadow-[0_18px_42px_rgba(17,24,39,0.06)] sm:px-8 lg:px-10"> )}
<div className="page-detail-content prose tiptap max-w-none overflow-hidden">
<StructuredPostContent post={post} />
</div>
</div>
<div className="page-detail-styles"> <div className="page-detail-styles">
<style jsx global>{` <style jsx global>{`
......
...@@ -46,13 +46,37 @@ function StructuredImageSection({ section }: { section: DynamicPostContentSectio ...@@ -46,13 +46,37 @@ function StructuredImageSection({ section }: { section: DynamicPostContentSectio
); );
} }
function normalizeCaptionShortcodes(html: string) {
return html.replace(/\[caption[^\]]*]([\s\S]*?)\[\/caption]/gi, (_match, innerContent: string) => {
const normalizedInnerContent = innerContent.trim();
const imageMatch = normalizedInnerContent.match(/(<img[\s\S]*?>)([\s\S]*)/i);
if (!imageMatch) {
return normalizedInnerContent;
}
const imageHtml = imageMatch[1]?.trim() ?? "";
const captionText = imageMatch[2]?.trim() ?? "";
if (!captionText) {
return imageHtml;
}
return `<figure>${imageHtml}<figcaption>${captionText}</figcaption></figure>`;
});
}
function renderStructuredHtml(html: string) {
return parse(normalizeCaptionShortcodes(html));
}
export default function StructuredPostContent({ post }: StructuredPostContentProps) { export default function StructuredPostContent({ post }: StructuredPostContentProps) {
const sections = (post.content_structure?.post_content ?? []) const sections = (post.content_structure?.post_content ?? [])
.slice() .slice()
.sort((left, right) => left.position - right.position); .sort((left, right) => left.position - right.position);
if (!sections.length) { if (!sections.length) {
return <>{parse(getDynamicPostBodyHtml(post))}</>; return <>{renderStructuredHtml(getDynamicPostBodyHtml(post))}</>;
} }
const hasRenderableSection = sections.some( const hasRenderableSection = sections.some(
...@@ -60,7 +84,7 @@ export default function StructuredPostContent({ post }: StructuredPostContentPro ...@@ -60,7 +84,7 @@ export default function StructuredPostContent({ post }: StructuredPostContentPro
); );
if (!hasRenderableSection) { if (!hasRenderableSection) {
return <>{parse(getDynamicPostBodyHtml(post))}</>; return <>{renderStructuredHtml(getDynamicPostBodyHtml(post))}</>;
} }
return ( return (
...@@ -73,7 +97,7 @@ export default function StructuredPostContent({ post }: StructuredPostContentPro ...@@ -73,7 +97,7 @@ export default function StructuredPostContent({ post }: StructuredPostContentPro
const content = section.content.trim(); const content = section.content.trim();
if (!content) return null; if (!content) return null;
return <div key={section.id}>{parse(content)}</div>; return <div key={section.id}>{renderStructuredHtml(content)}</div>;
})} })}
</> </>
); );
......
'use client';
import StructuredPostContent from "../StructuredPostContent";
import type { DynamicPostItem } from "../types";
type DefaultInformationPageProps = {
post: DynamicPostItem;
};
export default function DefaultInformationPage({
post,
}: DefaultInformationPageProps) {
return (
<section className="block">
<div className="min-w-0">
<h1 className="max-w-6xl text-3xl font-bold leading-tight text-[#111827] md:text-[38px] md:leading-[1.15]">
{post.title}
</h1>
<div className="mt-3 h-[3px] w-16 rounded-full bg-[#f5a400]" />
{post.summary ? (
<p className="mt-5 max-w-6xl text-base font-semibold leading-7 text-[#374151] md:text-lg md:leading-8">
{post.summary}
</p>
) : null}
<div className="mt-7 rounded-3xl bg-white px-5 py-6 shadow-[0_18px_42px_rgba(17,24,39,0.06)] sm:px-8 lg:px-10">
<div className="page-detail-content prose tiptap max-w-none overflow-hidden">
<StructuredPostContent post={post} />
</div>
</div>
</div>
</section>
);
}
'use client';
import {
BadgeCheck,
Bell,
Globe2,
Mail,
MapPin,
MessageCircleMore,
Phone,
ShieldCheck,
TrendingUp,
WalletCards,
} from "lucide-react";
const MEMBER_BENEFITS = [
{
key: "voice",
title: "Tiếng nói",
icon: MessageCircleMore,
iconClassName: "bg-[#f59e0b]",
bullets: [
"Được hỗ trợ giải quyết các vướng mắc, kiến nghị của doanh nghiệp với các cơ quan quản lý trong quá trình kinh doanh và thực thi pháp luật.",
"Được tham dự miễn phí các hội nghị, hội thảo, đối thoại với các cơ quan ban ngành về pháp luật và chính sách hàng năm.",
"Được tham dự hội nghị đối thoại thường niên về chính sách thuế, hải quan và thủ tục hành chính.",
],
},
{
key: "recognition",
title: "Độ nhận diện",
icon: BadgeCheck,
iconClassName: "bg-[#1f2937]",
bullets: [
"Hồ sơ doanh nghiệp được đăng tải miễn phí trên Danh bạ Hội viên CONNECTIONS.",
"Thông tin doanh nghiệp được giới thiệu miễn phí trên website và các kênh truyền thông của VCCI-HCM.",
"Cơ hội trở thành nhà tài trợ cho các sự kiện của VCCI-HCM.",
"Được ưu đãi đặc biệt khi sử dụng các dịch vụ truyền thông, quảng bá thương hiệu của VCCI-HCM.",
],
},
{
key: "network",
title: "Mạng lưới liên kết",
icon: Globe2,
iconClassName: "bg-[#10b981]",
bullets: [
"Được tham dự miễn phí các sự kiện xúc tiến thương mại và đầu tư hằng năm.",
"Được ưu đãi khi tham gia các đoàn khảo sát thị trường nước ngoài do VCCI-HCM tổ chức.",
"Tương tác trong mạng lưới hội viên VCCI-HCM, tiếp cận các đối tác tin cậy và khách hàng tiềm năng.",
],
},
{
key: "growth",
title: "Phát triển",
icon: TrendingUp,
iconClassName: "bg-[#3b82f6]",
bullets: [
"Được tham gia các khóa đào tạo của VCCI-HCM với chi phí ưu đãi.",
"Được tiếp cận các dự án hỗ trợ doanh nghiệp phát triển được tài trợ bởi các tổ chức trong nước và quốc tế.",
"Được tư vấn bởi các chuyên gia về pháp luật, quan hệ lao động, thị trường,... với chi phí ưu đãi.",
],
},
{
key: "trust",
title: "Độ tin cậy",
icon: ShieldCheck,
iconClassName: "bg-[#9333ea]",
bullets: [
"Tăng uy tín và độ tin cậy cho doanh nghiệp khi trở thành hội viên VCCI-HCM.",
"Tạo thuận lợi cho doanh nghiệp trong các hoạt động hợp tác kinh doanh - đầu tư.",
],
},
{
key: "information",
title: "Thông tin",
icon: Bell,
iconClassName: "bg-[#ef4444]",
bullets: [
"Được nhận miễn phí Bản tin điện tử phát hành hằng tháng và Tạp chí VCCI-HCM phát hành hằng quý.",
"Được nhận miễn phí Danh bạ Hội viên VCCI-HCM.",
"Được nhận các sản phẩm thông tin phục vụ cho doanh nghiệp và các nhà đầu tư.",
],
},
] as const;
export default function MemberBenefitsPage() {
return (
<section className="grid gap-8 lg:grid-cols-[minmax(0,1fr)_320px] lg:items-start">
<div>
<h1 className="text-3xl font-bold leading-tight text-[#111827] md:text-[38px] md:leading-[1.15]">
Lợi ích của hội viên VCCI
</h1>
<div className="mt-3 h-[3px] w-14 rounded-full bg-[#f5a400]" />
<div className="mt-7 space-y-7">
{MEMBER_BENEFITS.map((section) => {
const Icon = section.icon;
return (
<article key={section.key} className="flex items-start gap-4">
<div
className={`mt-1 flex h-11 w-11 shrink-0 items-center justify-center rounded-2xl text-white shadow-[0_12px_30px_rgba(17,24,39,0.12)] ${section.iconClassName}`}
>
<Icon className="h-5 w-5" />
</div>
<div className="min-w-0">
<h2 className="text-[30px] font-bold leading-tight text-[#1f2a44]">
{section.title}
</h2>
<ul className="mt-3 space-y-2.5">
{section.bullets.map((bullet) => (
<li
key={bullet}
className="flex items-start gap-3 text-[16px] leading-8 text-[#5f6f86]"
>
<span className="mt-3 h-2 w-2 shrink-0 rounded-full bg-[#f5a400]" />
<span>{bullet}</span>
</li>
))}
</ul>
</div>
</article>
);
})}
</div>
</div>
<aside className="rounded-[28px] bg-[#1c56a1] px-6 py-6 text-white shadow-[0_22px_46px_rgba(28,52,120,0.18)] lg:sticky lg:top-24">
<h2 className="text-[28px] font-bold leading-tight">Liên hệ</h2>
<div className="mt-6 space-y-5 text-[15px] leading-7 text-white/90">
<div>
<div className="flex items-center gap-2 text-[#f5c21b]">
<Phone className="h-4 w-4" />
<span className="font-semibold">Phòng Hội viên và Đào tạo</span>
</div>
<p className="mt-1">C. Thanh Thủy</p>
<p>ĐT: 0903 909 796</p>
</div>
<div>
<div className="flex items-center gap-2 text-[#f5c21b]">
<Mail className="h-4 w-4" />
<span className="font-semibold">Email</span>
</div>
<p className="mt-1 wrap-break-word">luuthanhthuy72@yahoo.com</p>
<p className="wrap-break-word">hoivien@vcci-hcm.org.vn</p>
</div>
<div>
<div className="flex items-center gap-2 text-[#f5c21b]">
<WalletCards className="h-4 w-4" />
<span className="font-semibold">Điện thoại</span>
</div>
<p className="mt-1">028. 3932 0817 - Fax: 028. 3932 5472</p>
</div>
<div>
<div className="flex items-center gap-2 text-[#f5c21b]">
<MapPin className="h-4 w-4" />
<span className="font-semibold">Địa chỉ</span>
</div>
<p className="mt-1">
P. 306, Lầu 3, Tòa nhà VCCI, 171 Võ Thị Sáu,
<br />
Quận 3, TP. Hồ Chí Minh
</p>
</div>
</div>
</aside>
</section>
);
}
'use client';
import type { DynamicPostItem } from "../types";
type MemberRegistrationPageProps = {
post: DynamicPostItem;
};
const MEMBERSHIP_REQUIREMENTS = [
"Đơn xin gia nhập làm hội viên chính thức VCCI (2 bản theo mẫu của VCCI)",
"Giấy phép đăng ký kinh doanh, hoặc giấy phép thành lập hoặc quyết định thành lập (2 bản sao)",
];
const MEMBERSHIP_FEES = [
"Doanh số dưới 10 tỉ đồng đóng 3 triệu đồng/năm",
"Doanh số từ 10 - 50 tỉ đồng đóng 7 triệu đồng/năm",
"Doanh số trên 50 tỉ đồng đóng 15 triệu đồng/năm",
];
const ATTACHED_FORMS = [
{
label: "Đơn đăng ký tham gia nhập hội viên VCCI (Mẫu Doanh nghiệp)",
href: "/Don-dang-ky-tham-gia-nhap-hoi-vien-VCCI_Mau-Doanh-nghiep-1.docx",
download: true,
},
{
label: "Đơn đăng ký tham gia nhập hội viên VCCI (Mẫu Hiệp hội)",
href: "/Don-dang-ky-tham-gia-nhap-hoi-vien-VCCI_Mau-Hiep-hoi.docx",
download: true,
},
{
label: "Hướng dẫn hồ sơ đăng ký Hội viên VCCI",
href: "https://vccihcm.vn/dang-ky",
download: false,
},
] as const;
export default function MemberRegistrationPage({ post }: MemberRegistrationPageProps) {
return (
<section className="">
<div className="min-w-0">
<h1 className="max-w-6xl text-3xl font-bold leading-tight text-[#111827] md:text-[38px] md:leading-[1.15]">
Đăng ký hội viên
</h1>
<div className="mt-3 h-[3px] w-16 rounded-full bg-[#f5a400]" />
<div className="mt-7 space-y-7 rounded-3xl bg-white px-5 py-6 shadow-[0_18px_42px_rgba(17,24,39,0.06)] sm:px-8 lg:px-10">
<p className="text-justify text-[18px] leading-9 text-[#1f2a44]">
{post.content?.trim() ||
"Điều lệ sửa đổi của Liên đoàn Thương mại và Công nghiệp Việt Nam (VCCI) được Đại hội đại biểu toàn quốc VCCI lần thứ VII thông qua và được Thủ tướng Chính phủ phê duyệt tại Quyết định số 1496/QĐ-TTg ngày 30/11/2022 đã quy định tất cả các doanh nghiệp, các tổ chức sản xuất, kinh doanh, người sử dụng lao động, các hiệp hội doanh nghiệp có đăng ký và hoạt động hợp pháp ở Việt Nam đều có thể trở thành hội viên của VCCI."}
</p>
<p className="text-justify text-[18px] leading-9 text-[#1f2a44]">
Để trở thành hội viên chính thức, tổ chức quan tâm cần gửi VCCI tại Hà Nội hoặc các Chi nhánh, Văn phòng đại diện của VCCI hồ sơ gia nhập gồm:
</p>
<ul className="space-y-2 pl-6 text-[18px] leading-9 text-[#1f2a44]">
{MEMBERSHIP_REQUIREMENTS.map((item) => (
<li key={item} className="list-disc">
<strong>{item}</strong>
</li>
))}
</ul>
<p className="text-justify text-[18px] leading-9 text-[#1f2a44]">
Khi nhận được đơn, Ban Thường trực sẽ xét và thông báo cho tổ chức liên quan về quyết định kết nạp. Trong vòng 1 tháng kể từ ngày nhận thông báo, tổ chức phải thực hiện đóng lệ phí gia nhập. Chỉ khi nào tổ chức đóng lệ phí gia nhập mới được coi là hội viên chính thức. Theo quyết định của Ban chấp hành VCCI, lệ phí hiện hành được tính như sau:
</p>
<p className="text-justify text-[18px] leading-9 text-[#1f2a44]">
Mức lệ phí gia nhập bằng mức hội phí hàng năm, được tính căn cứ vào doanh số của tổ chức trong năm trước theo các mức:
</p>
<ul className="space-y-2 pl-6 text-[18px] leading-9 text-[#1f2a44]">
{MEMBERSHIP_FEES.map((item) => (
<li key={item} className="list-disc">
{item}
</li>
))}
</ul>
<p className="text-justify text-[18px] leading-9 text-[#1f2a44]">
Mức lệ phí gia nhập và hội phí trên có thể được điều chỉnh bởi quyết định của Ban chấp hành VCCI trong từng thời gian cụ thể.
</p>
<div>
<p className="font-semibold text-[#2450b5]">Để biết thêm thông tin chi tiết, vui lòng liên hệ:</p>
<div className="mt-4 space-y-1 text-[18px] leading-9 text-[#1f2a44]">
<p className="font-semibold">Phòng Hội viên Đào tạo và Truyền thông:</p>
<p>C. Thúy – ĐD: 0903 909 756</p>
<p>Email: luuthanhthuy72@yahoo.com; hoivien@vcci-hcm.org.vn;</p>
<p>Điện thoại: 028. 3932 0611 – Fax: 028. 3932 5472</p>
<p>Địa chỉ: P. 306, Lầu 3, Tòa nhà VCCI, 171 Võ Thị Sáu, Phường Xuân Hòa, TP. Hồ Chí Minh</p>
</div>
</div>
<div>
<p className="font-semibold text-[#1f2a44]">Biểu mẫu đính kèm:</p>
<ul className="mt-3 space-y-2 pl-6 text-[#2450b5]">
{ATTACHED_FORMS.map((item) => (
<li key={item.label} className="list-disc italic">
{item.download ? (
<a href={item.href} download className="hover:text-[#173f9f]">
{item.label}
</a>
) : (
<a href={item.href} target="_blank" rel="noreferrer" className="hover:text-[#173f9f]">
{item.label}
</a>
)}
</li>
))}
</ul>
</div>
<div className="flex justify-center pt-4">
<a
href="https://vccihcm.vn/dang-ky"
target="_blank"
rel="noreferrer"
className="inline-flex min-w-[220px] items-center justify-center rounded-[4px] bg-[#2450b5] px-6 py-4 text-[18px] font-semibold text-white transition-colors hover:bg-[#173f9f]"
>
Đăng ký Hội viên
</a>
</div>
</div>
</div>
</section>
);
}
'use client';
import {
BriefcaseBusiness,
CalendarDays,
FileBadge2,
GraduationCap,
Languages,
Megaphone,
Scale,
Search,
Store,
Ticket,
} from "lucide-react";
import type { DynamicPostItem } from "../types";
const SERVICE_SUPPORT_ITEMS = [
{
key: "events",
title: "Tổ chức sự kiện, hội nghị, hội thảo, giao lưu thương mại, hội chợ, triển lãm",
icon: CalendarDays,
},
{
key: "training",
title: "Đào tạo nâng cao năng lực quản trị doanh nghiệp",
icon: GraduationCap,
},
{
key: "market",
title: "Khảo sát thị trường nước ngoài",
icon: Search,
},
{
key: "venue",
title: "Cho thuê văn phòng, hội trường",
icon: Store,
},
{
key: "media",
title: "Quảng cáo, truyền thông",
icon: Megaphone,
},
{
key: "legal",
title: "Tư vấn về pháp lý, quan hệ lao động, môi trường kinh doanh",
icon: Scale,
},
{
key: "certificate",
title: "Cấp C/O và xác nhận các chứng từ thương mại",
icon: FileBadge2,
},
{
key: "business-info",
title: "Cung cấp thông tin thị trường và hồ sơ doanh nghiệp",
icon: BriefcaseBusiness,
},
{
key: "visa",
title: "Thu xếp visa nhập cảnh",
icon: Ticket,
},
{
key: "translate",
title: "Phiên biên dịch",
icon: Languages,
},
] as const;
type ServicePageProps = {
post: DynamicPostItem;
};
export default function ServicePage({ post }: ServicePageProps) {
const introText =
post.summary?.trim() ||
"VCCI-HCM cung cấp đa dạng các dịch vụ hỗ trợ doanh nghiệp phát triển và hội nhập kinh tế quốc tế.";
return (
<section className="grid gap-8 lg:grid-cols-[minmax(0,0.8fr)_minmax(0,1.2fr)] lg:items-start">
<div className="">
<h1 className="text-3xl font-bold leading-tight text-[#111827] md:text-[38px] md:leading-[1.15]">
Dịch vụ cung cấp
</h1>
<div className="mt-3 h-[3px] w-14 rounded-full bg-[#f5a400]" />
<p className="mt-5 max-w-[520px] text-[18px] leading-9 text-[#66758d]">
{introText}
</p>
</div>
<div className="overflow-hidden rounded-4xl border border-[#d9e3f2] bg-white shadow-[0_22px_46px_rgba(28,52,120,0.12)]">
<div className="bg-[#19519c] px-5 py-5 text-white md:px-6">
<div className="flex flex-wrap items-center justify-between gap-3">
<div>
<h2 className="text-[26px] font-bold leading-tight">Danh mục hỗ trợ</h2>
<p className="mt-1 text-sm text-white/80">
Dành cho hội viên, doanh nghiệp và đối tác thương mại
</p>
</div>
<span className="inline-flex rounded-full bg-white/12 px-4 py-1.5 text-xs font-semibold tracking-[0.24em] text-white/92">
VCCI-HCM
</span>
</div>
</div>
<div className="grid md:grid-cols-2">
{SERVICE_SUPPORT_ITEMS.map((item, index) => {
const Icon = item.icon;
const isRightColumn = index % 2 === 1;
const isLastRow = index >= SERVICE_SUPPORT_ITEMS.length - 2;
return (
<div
key={item.key}
className={[
"flex min-h-28 items-start gap-4 px-5 py-5 md:px-6",
!isLastRow ? "border-b border-[#e7edf7]" : "",
isRightColumn ? "md:border-l md:border-[#e7edf7]" : "",
].join(" ")}
>
<div className="flex h-11 w-11 shrink-0 items-center justify-center rounded-full bg-[#fff8ea] text-[#5c6f8d]">
<Icon className="h-5 w-5" />
</div>
<p className="pt-1 text-[18px] leading-8 text-[#5f6f86]">
{item.title}
</p>
</div>
);
})}
</div>
</div>
</section>
);
}
export const ABOUT_VCCI_HCM_SLUG = "ve-vcci-hcm";
export const SERVICE_PAGE_SLUG = "dich-vu-cung-cap";
export const MEMBER_BENEFITS_PAGE_SLUG = "loi-ich-hoi-vien-vcci";
export const MEMBER_REGISTRATION_PAGE_SLUG = "dang-ky-hoi-vien";
export const MARKET_PROFILE_PAGE_SLUG = "ho-so-thi-truong";
export const LEGAL_TRADE_PAGE_SLUG =
"phap-che-cap-giay-chung-nhan-va-xac-nhan-chung-tu-thuong-mai";
export { default as AboutVcciHcmPage } from "./AboutVcciHcmPage";
export { default as DefaultInformationPage } from "./DefaultInformationPage";
export { default as LegalTradePages } from "./legal-trade-pages";
export { default as MarketProfilePage } from "./MarketProfilePage";
export { default as MemberBenefitsPage } from "./MemberBenefitsPage";
export { default as MemberRegistrationPage } from "./MemberRegistrationPage";
export { default as ServicePage } from "./ServicePage";
export * from "./constants";
'use client';
import {
BadgeCheck,
Building2,
FileCheck2,
Files,
Globe2,
ShieldCheck,
} from "lucide-react";
import type { LegalTradePageProps } from "./types";
const DEFINITIONS = [
{
title: "Giấy chứng nhận của VCCI (VCCI Certificate)",
description:
"Là một loại chứng từ thương mại do VCCI phát hành trên phôi chính thức của VCCI, nhằm chứng nhận các khai báo của Thương nhân liên quan đến hoạt động mua bán, xuất khẩu, nhập khẩu, gia công, chế biến hàng hóa, dựa trên cơ sở các hồ sơ, tài liệu do Thương nhân đó xuất trình. Giấy chứng nhận này không phải là giấy chứng nhận xuất xứ hàng hóa (C/O) và không có giá trị thay thế C/O theo quy định của pháp luật Việt Nam và các điều ước quốc tế mà Việt Nam là thành viên.",
icon: BadgeCheck,
},
{
title: "Chứng từ thương mại (Commercial Document)",
description:
"Là các loại giấy tờ, tài liệu được sử dụng trong các giao dịch thương mại trong nước và quốc tế, bao gồm nhưng không giới hạn ở: Hóa đơn thương mại, Phiếu đóng gói, Vận đơn, Tờ khai hải quan hàng hóa xuất khẩu/nhập khẩu, Bảng kê chi tiết, Bảng giá, Giấy chứng nhận chất lượng, Giấy chứng nhận kiểm dịch và các tài liệu, chứng từ thương mại khác.",
icon: Files,
},
{
title: "Xác nhận chứng từ thương mại",
description:
"Là hành vi của VCCI, thông qua người có thẩm quyền, xác nhận bằng hình thức điện tử hoặc đóng dấu và ký tên lên một chứng từ thương mại phục vụ cho hoạt động xuất khẩu để chứng nhận rằng chứng từ đó, với số và ngày cụ thể, đã được một Thương nhân cụ thể xuất trình tại VCCI. Hành vi này không đồng nghĩa với việc VCCI bảo lãnh hay xác thực tính hợp pháp, tính chính xác về nội dung của chứng từ, hoặc thẩm quyền của bên phát hành gốc.",
icon: FileCheck2,
},
{
title: "Đơn vị cấp",
description:
"Đơn vị cấp Giấy chứng nhận, xác nhận Chứng từ thương mại của VCCI bao gồm Ban Pháp chế và các Chi nhánh VCCI được giao nhiệm vụ thực hiện công tác cấp Giấy chứng nhận, xác nhận Chứng từ thương mại.",
icon: Building2,
},
{
title: "Thương nhân (Trader)",
description:
"Là tổ chức kinh tế được thành lập hợp pháp, cá nhân hoạt động thương mại một cách độc lập, thường xuyên và có đăng ký kinh doanh tại Việt Nam.",
icon: ShieldCheck,
},
{
title: "Hệ thống COVCCI",
description:
"Là hệ thống dịch vụ trực tuyến của VCCI tại địa chỉ trang điện tử covcci.com.vn, được sử dụng để tiếp nhận khai báo, quản lý hồ sơ, cấp số tham chiếu và thực hiện các thủ tục liên quan đến việc cấp Giấy chứng nhận, xác nhận Chứng từ thương mại.",
icon: Globe2,
},
];
export default function CertificateTradeDocumentPage(_: LegalTradePageProps) {
return (
<section className="">
<div className="grid gap-8 lg:grid-cols-[minmax(0,1fr)_320px] lg:items-start">
<div className="min-w-0">
<h1 className="max-w-6xl text-3xl font-bold leading-tight text-[#111827] md:text-[38px] md:leading-[1.15]">
Giấy chứng nhận (GCN) và Chứng từ thương mại (CTTM)
</h1>
<div className="mt-3 h-[3px] w-16 rounded-full bg-[#f5a400]" />
<p className="mt-5 max-w-6xl text-base font-semibold leading-7 text-[#374151] md:text-lg md:leading-8">
Định nghĩa chung về Giấy chứng nhận của VCCI, Chứng từ thương mại và cơ chế xác nhận chứng từ phục vụ hoạt động thương mại, xuất khẩu của doanh nghiệp.
</p>
<div className="mt-7 rounded-3xl bg-white px-5 py-6 shadow-[0_18px_42px_rgba(17,24,39,0.06)] sm:px-8 lg:px-10">
<div className="rounded-[24px] border border-[#e5edf8] bg-[#f8fbff] px-5 py-5">
<p className="text-sm font-semibold uppercase tracking-[0.18em] text-[#2450b5]">Định nghĩa chung</p>
<p className="mt-3 text-[16px] leading-8 text-[#5f6f86]">
Nội dung dưới đây làm rõ phạm vi, bản chất pháp lý và cơ chế vận hành liên quan đến việc cấp Giấy chứng nhận và xác nhận Chứng từ thương mại tại VCCI.
</p>
</div>
<div className="mt-8 grid gap-4 xl:grid-cols-2">
{DEFINITIONS.map((item, index) => {
const Icon = item.icon;
return (
<article
key={item.title}
className={[
"rounded-[26px] border px-5 py-5 shadow-[0_14px_34px_rgba(17,24,39,0.06)]",
index === 0 || index === 2 ? "border-[#dbe7ff] bg-[#f8fbff]" : "border-[#edf1f6] bg-white",
].join(" ")}
>
<div className="flex h-11 w-11 items-center justify-center rounded-2xl bg-[#eff4ff] text-[#2450b5]">
<Icon className="h-5 w-5" />
</div>
<h2 className="mt-4 text-[21px] font-bold leading-tight text-[#1f2a44]">{item.title}</h2>
<p className="mt-3 text-[16px] leading-8 text-[#5f6f86]">{item.description}</p>
</article>
);
})}
</div>
</div>
</div>
<aside className="space-y-5 lg:sticky lg:top-24">
<div className="rounded-[28px] border border-[#edf1f6] bg-[#fbfcff] px-6 py-6 shadow-[0_18px_42px_rgba(17,24,39,0.05)]">
<h2 className="text-[28px] font-bold leading-tight text-[#1f2a44]">Thành phần chính</h2>
<div className="mt-5 space-y-4 text-[16px] leading-7 text-[#5f6f86]">
<div className="flex items-start gap-3">
<span className="mt-2 h-2.5 w-2.5 shrink-0 rounded-full bg-[#2f6ce5]" />
<span>Giấy chứng nhận của VCCI</span>
</div>
<div className="flex items-start gap-3">
<span className="mt-2 h-2.5 w-2.5 shrink-0 rounded-full bg-[#2f6ce5]" />
<span>Chứng từ thương mại trong giao dịch trong nước và quốc tế</span>
</div>
<div className="flex items-start gap-3">
<span className="mt-2 h-2.5 w-2.5 shrink-0 rounded-full bg-[#2f6ce5]" />
<span>Xác nhận chứng từ thương mại và Hệ thống COVCCI</span>
</div>
</div>
</div>
<div className="rounded-[28px] bg-linear-to-br from-[#1d56b7] to-[#21467f] px-6 py-6 text-white shadow-[0_22px_46px_rgba(28,52,120,0.18)]">
<h2 className="text-[26px] font-bold leading-tight">Ghi chú pháp lý</h2>
<div className="mt-5 space-y-4 text-[15px] leading-7 text-white/88">
<p>
Giấy chứng nhận của VCCI không phải là C/O và không có giá trị thay thế C/O theo quy định pháp luật hiện hành.
</p>
<p>
Việc xác nhận chứng từ thương mại không đồng nghĩa với việc VCCI bảo lãnh hay xác thực toàn bộ nội dung pháp lý của chứng từ gốc.
</p>
</div>
</div>
</aside>
</div>
</section>
);
}
'use client';
import { Mail, MapPin, Phone, UserRound } from "lucide-react";
import type { LegalTradePageProps } from "./types";
export default function ContactPage(_: LegalTradePageProps) {
return (
<section className="py-2">
<div className="grid gap-8 lg:grid-cols-[minmax(0,1fr)_320px] lg:items-start">
<div className="min-w-0">
<h1 className="max-w-6xl text-3xl font-bold leading-tight text-[#111827] md:text-[38px] md:leading-[1.15]">
Thông tin liên hệ
</h1>
<div className="mt-3 h-[3px] w-16 rounded-full bg-[#f5a400]" />
<div className="mt-7 space-y-5">
<article className="rounded-3xl border border-[#edf1f6] bg-white px-5 py-6 shadow-[0_18px_42px_rgba(17,24,39,0.06)] sm:px-8">
<h2 className="text-[24px] font-bold leading-tight text-[#1f2a44]">
Phòng Pháp chế và xác nhận Chứng từ thương mại
</h2>
<div className="mt-5 space-y-4 text-[16px] leading-8 text-[#5f6f86]">
<p>Liên đoàn Thương mại và Công nghiệp Việt Nam – Chi nhánh khu vực Thành phố Hồ Chí Minh (VCCI-HCM)</p>
<div className="flex items-start gap-3">
<MapPin className="mt-1 h-4 w-4 shrink-0 text-[#2450b5]" />
<span>Phòng 103, Lầu 1, Tòa nhà VCCI HCM, 171 Võ Thị Sáu, P. Xuân Hòa, TP. HCM</span>
</div>
<div className="flex items-start gap-3">
<Phone className="mt-1 h-4 w-4 shrink-0 text-[#2450b5]" />
<span>028-3932 6498</span>
</div>
<div className="flex items-start gap-3">
<Mail className="mt-1 h-4 w-4 shrink-0 text-[#2450b5]" />
<span>co@vcci-hcm.org.vn</span>
</div>
</div>
</article>
<article className="rounded-3xl border border-[#edf1f6] bg-white px-5 py-6 shadow-[0_18px_42px_rgba(17,24,39,0.06)] sm:px-8">
<h2 className="text-[24px] font-bold leading-tight text-[#1f2a44]">
Xử lý vướng mắc, phản ánh, góp ý trong quá trình làm thủ tục cấp GCN và xác nhận CTTM
</h2>
<div className="mt-5 space-y-5 text-[16px] leading-8 text-[#5f6f86]">
<div>
<p className="font-semibold text-[#1f2a44]">Điểm cấp số 1</p>
<p>Điện thoại: 028-3932 6498</p>
<p>Email: co@vcci-hcm.org.vn</p>
</div>
<div>
<p className="font-semibold text-[#1f2a44]">Điểm cấp số 2</p>
<p>Phó Trưởng phòng: Nguyễn Văn Đức</p>
<p>Mobile: 090 949 7155</p>
<p>Email: nvduc1980@gmail.com</p>
</div>
<div>
<p className="font-semibold text-[#1f2a44]">Điểm cấp số 3</p>
<p>Trưởng phòng (Cơ sở 2): Bà Ma Thị Hương</p>
<p>Mobile: 039 512 2922</p>
<p>Email: huongmtvccivt@gmail.com</p>
</div>
</div>
</article>
<article className="rounded-3xl border border-[#edf1f6] bg-white px-5 py-6 shadow-[0_18px_42px_rgba(17,24,39,0.06)] sm:px-8">
<h2 className="text-[24px] font-bold leading-tight text-[#1f2a44]">
Hướng dẫn hồ sơ và tiếp nhận phản ánh
</h2>
<div className="mt-5 space-y-5 text-[16px] leading-8 text-[#5f6f86]">
<div>
<p className="font-semibold text-[#1f2a44]">Hướng dẫn khai hồ sơ thương nhân, chữ ký số và IT</p>
<p>Điểm cấp số 1, điện thoại: 028-3932 6498</p>
<p>Điểm cấp số 2, điện thoại: 0274-380 0048</p>
<p>Điểm cấp số 3, điện thoại: 025-4385 2710</p>
</div>
<div>
<p className="font-semibold text-[#1f2a44]">Tiếp thu, giải quyết phản ánh, khiếu nại, góp ý</p>
<p>Trưởng phòng (Trụ sở chính): Ông Vũ Xuân Hưng</p>
<p>Điện thoại: 028-3932 6929 hoặc Mobile: 0909 170 171 (Đường dây nóng)</p>
<p>Email: vuxuanhung@vcci-hcm.org.vn</p>
</div>
</div>
</article>
</div>
</div>
<aside className="space-y-5 lg:sticky lg:top-24">
<div className="rounded-[28px] border border-[#edf1f6] bg-[#fbfcff] px-6 py-6 shadow-[0_18px_42px_rgba(17,24,39,0.05)]">
<h2 className="text-[28px] font-bold leading-tight text-[#1f2a44]">Đầu mối hỗ trợ</h2>
<div className="mt-5 space-y-4 text-[16px] leading-7 text-[#5f6f86]">
<div className="flex items-start gap-3">
<Mail className="mt-1 h-4 w-4 shrink-0 text-[#2450b5]" />
<span>co@vcci-hcm.org.vn</span>
</div>
<div className="flex items-start gap-3">
<Phone className="mt-1 h-4 w-4 shrink-0 text-[#2450b5]" />
<span>Đường dây nóng: 0909 170 171</span>
</div>
<div className="flex items-start gap-3">
<UserRound className="mt-1 h-4 w-4 shrink-0 text-[#2450b5]" />
<span>Ông Vũ Xuân Hưng</span>
</div>
</div>
</div>
</aside>
</div>
</section>
);
}
'use client';
import { CircleDollarSign, FileStack, Layers3 } from "lucide-react";
import type { LegalTradePageProps } from "./types";
const FEE_ITEMS = [
{
title: "Một bộ GCN, CTTM (4 bản)",
value: "100.000đ/bộ",
icon: FileStack,
},
{
title: "Bản làm thêm tính từ bản thứ 5 trở lên",
value: "10.000đ/bản",
icon: Layers3,
},
{
title: "Phôi Giấy chứng nhận",
value: "20.000đ/tờ",
icon: CircleDollarSign,
},
] as const;
export default function FeesPage(_: LegalTradePageProps) {
return (
<section className="">
<div className="grid gap-8 lg:grid-cols-[minmax(0,1fr)_320px] lg:items-start">
<div className="min-w-0">
<h1 className="max-w-6xl text-3xl font-bold leading-tight text-[#111827] md:text-[38px] md:leading-[1.15]">
Phí cấp GCN và xác nhận CTTM
</h1>
<div className="mt-3 h-[3px] w-16 rounded-full bg-[#f5a400]" />
<div className="mt-7 rounded-3xl bg-white px-5 py-6 shadow-[0_18px_42px_rgba(17,24,39,0.06)] sm:px-8 lg:px-10">
<div className="rounded-3xl border border-[#e5edf8] bg-[#f8fbff] px-5 py-5">
<p className="text-sm font-semibold uppercase tracking-[0.18em] text-[#2450b5]">Biểu phí hiện hành</p>
<p className="mt-3 text-[16px] leading-8 text-[#5f6f86]">
Mức phí áp dụng cho việc cấp Giấy chứng nhận và xác nhận Chứng từ thương mại được tính theo từng loại hồ sơ và số lượng bản phát hành.
</p>
</div>
<div className="mt-8 grid gap-4 md:grid-cols-3">
{FEE_ITEMS.map((item, index) => {
const Icon = item.icon;
return (
<article
key={item.title}
className={[
"rounded-[26px] border px-5 py-5 shadow-[0_14px_34px_rgba(17,24,39,0.06)]",
index === 0 ? "border-[#dbe7ff] bg-[#f8fbff]" : "border-[#edf1f6] bg-white",
].join(" ")}
>
<div className="flex h-11 w-11 items-center justify-center rounded-2xl bg-[#eff4ff] text-[#2450b5]">
<Icon className="h-5 w-5" />
</div>
<h2 className="mt-4 text-[20px] font-bold leading-tight text-[#1f2a44]">{item.title}</h2>
<p className="mt-4 text-[30px] font-bold leading-none text-[#2450b5]">{item.value}</p>
</article>
);
})}
</div>
</div>
</div>
<aside className="space-y-5 lg:sticky lg:top-24">
<div className="rounded-[28px] border border-[#edf1f6] bg-[#fbfcff] px-6 py-6 shadow-[0_18px_42px_rgba(17,24,39,0.05)]">
<h2 className="text-[28px] font-bold leading-tight text-[#1f2a44]">Tóm tắt chi phí</h2>
<div className="mt-5 space-y-4 text-[16px] leading-7 text-[#5f6f86]">
<div className="flex items-start gap-3">
<span className="mt-2 h-2.5 w-2.5 shrink-0 rounded-full bg-[#2f6ce5]" />
<span>01 bộ tiêu chuẩn gồm 4 bản</span>
</div>
<div className="flex items-start gap-3">
<span className="mt-2 h-2.5 w-2.5 shrink-0 rounded-full bg-[#2f6ce5]" />
<span>Có phụ phí cho bản làm thêm từ bản thứ 5</span>
</div>
<div className="flex items-start gap-3">
<span className="mt-2 h-2.5 w-2.5 shrink-0 rounded-full bg-[#2f6ce5]" />
<span>Phôi Giấy chứng nhận được tính riêng theo từng tờ</span>
</div>
</div>
</div>
<div className="rounded-[28px] bg-linear-to-br from-[#1d56b7] to-[#21467f] px-6 py-6 text-white shadow-[0_22px_46px_rgba(28,52,120,0.18)]">
<h2 className="text-[26px] font-bold leading-tight">Lưu ý khi chuẩn bị</h2>
<div className="mt-5 space-y-4 text-[15px] leading-7 text-white/88">
<p>Kiểm tra trước số lượng bản cần cấp để chuẩn bị đúng chi phí thực hiện.</p>
<p>Chuẩn bị lệ phí đầy đủ sẽ giúp quá trình tiếp nhận và xử lý hồ sơ diễn ra nhanh hơn.</p>
</div>
</div>
</aside>
</div>
</section>
);
}
'use client';
import { Download, FileBadge2, FileText } from "lucide-react";
import type { LegalTradePageProps } from "./types";
export default function FormsPage(_: LegalTradePageProps) {
return (
<section className="py-2">
<div className="grid gap-8 lg:grid-cols-[minmax(0,1fr)_320px] lg:items-start">
<div className="min-w-0">
<h1 className="max-w-6xl text-3xl font-bold leading-tight text-[#111827] md:text-[38px] md:leading-[1.15]">
Biểu mẫu GCN và nội dung khai báo GCN, CTTM
</h1>
<div className="mt-3 h-[3px] w-16 rounded-full bg-[#f5a400]" />
<div className="rounded-3xl bg-white px-5 py-6 shadow-[0_18px_42px_rgba(17,24,39,0.06)] sm:px-8 lg:px-10">
<div className="rounded-[26px] border border-[#edf1f6] bg-white px-5 py-5 shadow-[0_14px_34px_rgba(17,24,39,0.06)]">
<div className="flex items-start gap-4">
<div className="flex h-11 w-11 shrink-0 items-center justify-center rounded-2xl bg-[#eff4ff] text-[#2450b5]">
<FileText className="h-5 w-5" />
</div>
<div className="min-w-0 flex-1">
<h2 className="text-[22px] font-bold leading-tight text-[#1f2a44]">
bieu-mau-gcn-va-noi-dung-khai-bao-gcn-cttm.docx
</h2>
<p className="mt-3 text-[16px] leading-8 text-[#5f6f86]">
Nhấn tải xuống để xem toàn bộ biểu mẫu và nội dung khai báo.
</p>
<a
href="/bieu-mau-gcn-va-noi-dung-khai-bao-gcn-cttm.docx"
download
className="mt-5 inline-flex items-center gap-2 rounded-[4px] bg-[#2450b5] px-5 py-3 text-[15px] font-semibold text-white transition-colors hover:bg-[#173f9f]"
>
<Download className="h-4 w-4" />
Tải biểu mẫu
</a>
</div>
</div>
</div>
</div>
</div>
<aside className="space-y-5 lg:sticky lg:top-24">
<div className="rounded-[28px] border border-[#edf1f6] bg-[#fbfcff] px-6 py-6 shadow-[0_18px_42px_rgba(17,24,39,0.05)]">
<h2 className="text-[28px] font-bold leading-tight text-[#1f2a44]">Lưu ý</h2>
<div className="mt-5 space-y-4 text-[16px] leading-7 text-[#5f6f86]">
<div className="flex items-start gap-3">
<span className="mt-2 h-2.5 w-2.5 shrink-0 rounded-full bg-[#2f6ce5]" />
<span>Người dùng có thể tải về để xem biểu mẫu đầy đủ trên máy của mình.</span>
</div>
</div>
</div>
</aside>
</div>
</section>
);
}
'use client';
import {
Building2,
CircleDollarSign,
ClipboardList,
FileBadge2,
FileCheck2,
Mail,
MapPin,
Phone,
Scale,
ScrollText,
} from "lucide-react";
import type { LegalTradeTemplate } from "./types";
type LegalTradeLayoutProps = {
template: LegalTradeTemplate;
};
const ICONS = [Scale, FileCheck2, ScrollText, CircleDollarSign, Building2, ClipboardList];
export default function LegalTradeLayout({ template }: LegalTradeLayoutProps) {
return (
<section className="">
<div className="grid gap-8 lg:grid-cols-[minmax(0,1fr)_340px] lg:items-start">
<div className="min-w-0">
<h1 className="max-w-6xl text-3xl font-bold leading-tight text-[#111827] md:text-[38px] md:leading-[1.15]">
{template.pageTitle}
</h1>
<div className="mt-3 h-[3px] w-16 rounded-full bg-[#f5a400]" />
{template.intro ? (
<p className="mt-5 max-w-6xl text-base font-semibold leading-7 text-[#374151] md:text-lg md:leading-8">
{template.intro}
</p>
) : null}
<div className="mt-7 space-y-5">
{template.sections.map((section, index) => {
const Icon = ICONS[index % ICONS.length];
return (
<article
key={section.title}
className="rounded-3xl border border-[#edf1f6] bg-white px-5 py-6 shadow-[0_18px_42px_rgba(17,24,39,0.06)] sm:px-8"
>
<div className="flex items-start gap-4">
<div className="flex h-11 w-11 shrink-0 items-center justify-center rounded-2xl bg-[#eff4ff] text-[#2450b5]">
<Icon className="h-5 w-5" />
</div>
<div className="min-w-0 flex-1">
<h2 className="text-[24px] font-bold leading-tight text-[#1f2a44]">{section.title}</h2>
{section.description ? (
<p className="mt-4 text-[16px] leading-8 text-[#5f6f86]">{section.description}</p>
) : null}
{section.bullets?.length ? (
<ul className="mt-4 space-y-3 text-[16px] leading-8 text-[#5f6f86]">
{section.bullets.map((item) => (
<li key={item} className="flex items-start gap-3">
<span className="mt-3 h-2 w-2 shrink-0 rounded-full bg-[#f5a400]" />
<span>{item}</span>
</li>
))}
</ul>
) : null}
{section.numbered?.length ? (
<ol className="mt-4 space-y-4 text-[16px] leading-8 text-[#5f6f86]">
{section.numbered.map((item, itemIndex) => (
<li key={item} className="flex items-start gap-4">
<span className="mt-0.5 inline-flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-[#2450b5] text-sm font-bold text-white">
{itemIndex + 1}
</span>
<span>{item}</span>
</li>
))}
</ol>
) : null}
</div>
</div>
</article>
);
})}
</div>
</div>
<aside className="space-y-5 lg:sticky lg:top-24">
{template.sideCard ? (
<div className="rounded-[28px] border border-[#edf1f6] bg-[#fbfcff] px-6 py-6 shadow-[0_18px_42px_rgba(17,24,39,0.05)]">
<h2 className="text-[28px] font-bold leading-tight text-[#1f2a44]">{template.sideCard.title}</h2>
<div className="mt-5 space-y-4">
{template.sideCard.items.map((item) => (
<div key={item} className="flex items-start gap-3 text-[16px] leading-7 text-[#5f6f86]">
<span className="mt-2 h-2.5 w-2.5 shrink-0 rounded-full bg-[#2f6ce5]" />
<span>{item}</span>
</div>
))}
</div>
</div>
) : null}
<div className="rounded-[28px] bg-linear-to-br from-[#1d56b7] to-[#21467f] px-6 py-6 text-white shadow-[0_22px_46px_rgba(28,52,120,0.18)]">
<h2 className="text-[26px] font-bold leading-tight">Liên hệ hỗ trợ</h2>
<div className="mt-5 space-y-4 text-[15px] leading-7 text-white/88">
<div className="flex items-start gap-3">
<Phone className="mt-1 h-4 w-4 shrink-0 text-[#f5c21b]" />
<span>028-3932 6498</span>
</div>
<div className="flex items-start gap-3">
<Mail className="mt-1 h-4 w-4 shrink-0 text-[#f5c21b]" />
<span>co@vcci-hcm.org.vn</span>
</div>
<div className="flex items-start gap-3">
<MapPin className="mt-1 h-4 w-4 shrink-0 text-[#f5c21b]" />
<span>Phòng 103, Lầu 1, Tòa nhà VCCI HCM, 171 Võ Thị Sáu, P. Xuân Hòa, TP. HCM</span>
</div>
<div className="flex items-start gap-3">
<FileBadge2 className="mt-1 h-4 w-4 shrink-0 text-[#f5c21b]" />
<span>Hệ thống trực tuyến: covcci.com.vn</span>
</div>
</div>
</div>
</aside>
</div>
</section>
);
}
'use client';
import { Building2, Clock3, MapPin, Phone } from "lucide-react";
import type { LegalTradePageProps } from "./types";
const LOCATIONS = [
{
title: "Điểm cấp số 1",
address:
"Phòng 103, Lầu 1, Tòa nhà VCCI HCM, 171 Võ Thị Sáu, Phường Xuân Hòa, Thành phố Hồ Chí Minh",
phone: "028-3932 6498",
},
{
title: "Điểm cấp số 2",
address:
"Lầu 3, Tòa nhà Công ty CP ICD Tân Cảng Sóng Thần, Số 7/20, Đường ĐT 743, KP. Bình Đáng, Phường Bình Hòa, Thành phố Hồ Chí Minh",
phone: "0274-380 0048",
},
{
title: "Điểm cấp số 3",
address: "155 Nguyễn Thái Học, Phường Tam Thắng, Thành phố Hồ Chí Minh",
phone: "025-4385 2710",
},
] as const;
export default function LocationsPage(_: LegalTradePageProps) {
return (
<section className="">
<div className="grid gap-8 lg:grid-cols-[minmax(0,1fr)_320px] lg:items-start">
<div className="min-w-0">
<h1 className="max-w-6xl text-3xl font-bold leading-tight text-[#111827] md:text-[38px] md:leading-[1.15]">
Điểm cấp và cấp GCN và xác nhận CTTM
</h1>
<div className="mt-3 h-[3px] w-16 rounded-full bg-[#f5a400]" />
<div className="mt-7 rounded-3xl bg-white px-5 py-6 shadow-[0_18px_42px_rgba(17,24,39,0.06)] sm:px-8 lg:px-10">
<div className="rounded-3xl border border-[#e5edf8] bg-[#f8fbff] px-5 py-5">
<div className="flex items-center gap-3 text-[#2450b5]">
<Building2 className="h-5 w-5" />
<p className="text-sm font-semibold uppercase tracking-[0.18em]">
1. Các điểm cấp GCN và xác nhận CTTM thuộc VCCI-HCM
</p>
</div>
</div>
<div className="mt-8 grid gap-4">
{LOCATIONS.map((item, index) => (
<article
key={item.title}
className={[
"rounded-[26px] border px-5 py-5 shadow-[0_14px_34px_rgba(17,24,39,0.06)]",
index === 0 ? "border-[#dbe7ff] bg-[#f8fbff]" : "border-[#edf1f6] bg-white",
].join(" ")}
>
<div className="flex items-start gap-4">
<span className="inline-flex h-11 w-11 shrink-0 items-center justify-center rounded-2xl bg-[#eff4ff] text-lg font-bold text-[#2450b5]">
{index + 1}
</span>
<div className="min-w-0 flex-1">
<h2 className="text-[22px] font-bold leading-tight text-[#1f2a44]">{item.title}</h2>
<div className="mt-4 space-y-3 text-[16px] leading-8 text-[#5f6f86]">
<div className="flex items-start gap-3">
<MapPin className="mt-1 h-4 w-4 shrink-0 text-[#2450b5]" />
<span>{item.address}</span>
</div>
<div className="flex items-start gap-3">
<Phone className="mt-1 h-4 w-4 shrink-0 text-[#2450b5]" />
<span>{item.phone}</span>
</div>
</div>
</div>
</div>
</article>
))}
</div>
<div className="mt-8 rounded-3xl border border-[#dbe7ff] bg-[#f8fbff] px-5 py-5">
<div className="flex items-center gap-3 text-[#2450b5]">
<Clock3 className="h-5 w-5" />
<p className="text-sm font-semibold uppercase tracking-[0.18em]">2. Giờ tiếp nhận hồ sơ</p>
</div>
<div className="mt-4 space-y-2 text-[16px] leading-8 text-[#5f6f86]">
<p>– Từ thứ Hai đến thứ Sáu</p>
<p>Buổi sáng: 7h30 – 11h30</p>
<p>Buổi chiều: 13h30 – 16h30</p>
<p>Thời gian cấp: không quá 08 giờ làm việc</p>
</div>
</div>
</div>
</div>
<aside className="space-y-5 lg:sticky lg:top-24">
<div className="rounded-[28px] border border-[#edf1f6] bg-[#fbfcff] px-6 py-6 shadow-[0_18px_42px_rgba(17,24,39,0.05)]">
<h2 className="text-[28px] font-bold leading-tight text-[#1f2a44]">Liên hệ nhanh</h2>
<div className="mt-5 space-y-4 text-[16px] leading-7 text-[#5f6f86]">
{LOCATIONS.map((item) => (
<div key={item.title} className="flex items-start gap-3">
<span className="mt-2 h-2.5 w-2.5 shrink-0 rounded-full bg-[#2f6ce5]" />
<span>
{item.title}: {item.phone}
</span>
</div>
))}
</div>
</div>
<div className="rounded-[28px] bg-linear-to-br from-[#1d56b7] to-[#21467f] px-6 py-6 text-white shadow-[0_22px_46px_rgba(28,52,120,0.18)]">
<h2 className="text-[26px] font-bold leading-tight">Khung giờ làm việc</h2>
<div className="mt-5 space-y-4 text-[15px] leading-7 text-white/88">
<p>Từ thứ Hai đến thứ Sáu</p>
<p>Buổi sáng: 7h30 – 11h30</p>
<p>Buổi chiều: 13h30 – 16h30</p>
<p>Thời gian cấp: không quá 08 giờ làm việc</p>
</div>
</div>
</aside>
</div>
</section>
);
}
'use client';
import { BriefcaseBusiness, FileText, GraduationCap, Mail, Phone, Scale } from "lucide-react";
import type { LegalTradePageProps } from "./types";
const PHAP_CHE_SERVICES = [
{
title: "Góp ý và hỗ trợ pháp lý",
description:
"Tập hợp ý kiến góp ý xây dựng pháp luật, tiếp nhận các khó khăn, vướng mắc trong hoạt động kinh doanh của doanh nghiệp.",
icon: Scale,
},
{
title: "Tư vấn chuyên sâu",
description:
"Tư vấn, kết nối và cung cấp dịch vụ pháp lý kinh doanh chuyên sâu (Luật sư/ Trọng tài viên).",
icon: FileText,
},
{
title: "Dịch vụ thương mại",
description:
"Dịch vụ xuất khẩu, nhập khẩu; Chứng nhận lãnh sự; Phân loại HS; C/O; Lộ trình thuế quan trong các FTA; …",
icon: BriefcaseBusiness,
},
{
title: "Đào tạo chuyên sâu",
description:
"Tổ chức tập huấn đào tạo chuyên sâu trong các lĩnh vực Thuế; Hải quan; Tài chính kế toán; Phân loại mã số hàng hóa (Mã HS); Xuất xứ hàng hóa; Những vấn đề pháp lý của hợp đồng mua bán hàng hóa trong nước và quốc tế; …",
icon: GraduationCap,
},
];
export default function PhapChePage(_: LegalTradePageProps) {
return (
<section className="">
<div className="grid gap-8 lg:grid-cols-[minmax(0,1fr)_320px] lg:items-start">
<div className="min-w-0">
<h1 className="max-w-6xl text-3xl font-bold leading-tight text-[#111827] md:text-[38px] md:leading-[1.15]">
Pháp chế
</h1>
<div className="mt-3 h-[3px] w-16 rounded-full bg-[#f5a400]" />
<div className="mt-7 rounded-3xl bg-white px-5 py-6 shadow-[0_18px_42px_rgba(17,24,39,0.06)] sm:px-8 lg:px-10">
<div className="grid gap-4 md:grid-cols-2">
<div className="rounded-[24px] border border-[#e5edf8] bg-[#f8fbff] px-5 py-5">
<div className="flex items-center gap-3 text-[#2450b5]">
<Phone className="h-5 w-5" />
<span className="text-sm font-semibold uppercase tracking-[0.18em]">Điện thoại</span>
</div>
<p className="mt-3 text-[28px] font-bold text-[#1f2a44]">028-3932 6498</p>
</div>
<div className="rounded-[24px] border border-[#e5edf8] bg-[#f8fbff] px-5 py-5">
<div className="flex items-center gap-3 text-[#2450b5]">
<Mail className="h-5 w-5" />
<span className="text-sm font-semibold uppercase tracking-[0.18em]">Email</span>
</div>
<p className="mt-3 break-words text-[22px] font-bold text-[#1f2a44]">co@vcci-hcm.org.vn</p>
</div>
</div>
<div className="mt-8 grid gap-4 xl:grid-cols-2">
{PHAP_CHE_SERVICES.map((item) => {
const Icon = item.icon;
return (
<article
key={item.title}
className="rounded-[26px] border border-[#edf1f6] bg-white px-5 py-5 shadow-[0_14px_34px_rgba(17,24,39,0.06)]"
>
<div className="flex h-11 w-11 items-center justify-center rounded-2xl bg-[#eff4ff] text-[#2450b5]">
<Icon className="h-5 w-5" />
</div>
<h2 className="mt-4 text-[22px] font-bold leading-tight text-[#1f2a44]">{item.title}</h2>
<p className="mt-3 text-[16px] leading-8 text-[#5f6f86]">{item.description}</p>
</article>
);
})}
</div>
</div>
</div>
<aside className="space-y-5 lg:sticky lg:top-24">
<div className="rounded-[28px] border border-[#edf1f6] bg-[#fbfcff] px-6 py-6 shadow-[0_18px_42px_rgba(17,24,39,0.05)]">
<h2 className="text-[28px] font-bold leading-tight text-[#1f2a44]">Phạm vi hỗ trợ</h2>
<div className="mt-5 space-y-4 text-[16px] leading-7 text-[#5f6f86]">
<div className="flex items-start gap-3">
<span className="mt-2 h-2.5 w-2.5 shrink-0 rounded-full bg-[#2f6ce5]" />
<span>Góp ý xây dựng pháp luật và tiếp nhận vướng mắc doanh nghiệp</span>
</div>
<div className="flex items-start gap-3">
<span className="mt-2 h-2.5 w-2.5 shrink-0 rounded-full bg-[#2f6ce5]" />
<span>Tư vấn và kết nối chuyên gia pháp lý kinh doanh</span>
</div>
<div className="flex items-start gap-3">
<span className="mt-2 h-2.5 w-2.5 shrink-0 rounded-full bg-[#2f6ce5]" />
<span>Đào tạo chuyên sâu về thuế, hải quan, xuất xứ và hợp đồng</span>
</div>
</div>
</div>
<div className="rounded-[28px] bg-linear-to-br from-[#1d56b7] to-[#21467f] px-6 py-6 text-white shadow-[0_22px_46px_rgba(28,52,120,0.18)]">
<h2 className="text-[26px] font-bold leading-tight">Liên hệ Pháp chế</h2>
<div className="mt-5 space-y-4 text-[15px] leading-7 text-white/88">
<div className="flex items-start gap-3">
<Phone className="mt-1 h-4 w-4 shrink-0 text-[#f5c21b]" />
<span>028-3932 6498</span>
</div>
<div className="flex items-start gap-3">
<Mail className="mt-1 h-4 w-4 shrink-0 text-[#f5c21b]" />
<span>co@vcci-hcm.org.vn</span>
</div>
</div>
</div>
</aside>
</div>
</section>
);
}
'use client';
import { Clock3, FileCheck2, FileUp, Landmark, ReceiptText, RotateCcw } from "lucide-react";
import type { LegalTradePageProps } from "./types";
const REQUIREMENTS = [
"Đăng ký tài khoản Thương nhân và khai báo các trường thông tin của Thương nhân trên Hệ thống COVCCI.",
"Liên hệ với Đơn vị cấp Giấy chứng nhận, xác nhận Chứng từ thương mại của VCCI kích hoạt tài khoản cho Thương nhân.",
];
const STEPS = [
{
title: "Bước 1. Khai báo trực tuyến",
description:
"Thương nhân truy cập Hệ thống COVCCI, thực hiện khai báo các thông tin theo hướng dẫn, đính kèm hồ sơ dưới dạng điện tử đã được Thương nhân xác nhận bằng chữ ký số do cơ quan có thẩm quyền cấp và nhận số tham chiếu cho bộ hồ sơ.",
icon: FileUp,
},
{
title: "Bước 2. Thanh toán giá dịch vụ và hồ sơ giấy",
description:
"Thương nhân thanh toán giá dịch vụ và bộ hồ sơ giấy đầy đủ theo quy định tại bộ phận tiếp nhận của đơn vị VCCI có thẩm quyền.",
icon: ReceiptText,
},
{
title: "Bước 3. Phân công và thẩm định",
description:
"Bộ phận tiếp nhận hồ sơ kiểm tra tính đầy đủ, hợp lệ ban đầu và phân công cho cán bộ nghiệp vụ xử lý.",
icon: FileCheck2,
},
{
title: "Bước 4. Phê duyệt và cấp",
description:
"Nếu hồ sơ hợp lệ và đầy đủ, cán bộ nghiệp vụ trình hồ sơ lên người có thẩm quyền ký duyệt. Sau khi được ký duyệt, chứng từ sẽ được đóng dấu, tách, lưu trữ (hoặc vào hộp) và trả kết quả cho Thương nhân.",
icon: Landmark,
},
{
title: "Bước 5. Trả hồ sơ hoặc yêu cầu bổ sung",
description:
"Nếu hồ sơ có sai sót, không hợp lệ hoặc vi phạm các quy định, cán bộ nghiệp vụ thông báo rõ lý do cho Thương nhân (thông qua hệ thống hoặc trực tiếp) để yêu cầu sửa đổi, bổ sung hoặc từ chối cấp.",
icon: RotateCcw,
},
];
export default function ProcedurePage(_: LegalTradePageProps) {
return (
<section className="">
<div className="grid gap-8 lg:grid-cols-[minmax(0,1fr)_320px] lg:items-start">
<div className="min-w-0">
<h1 className="max-w-6xl text-3xl font-bold leading-tight text-[#111827] md:text-[38px] md:leading-[1.15]">
Quy trình tiếp nhận hồ sơ cấp GCN và xác nhận CTTM
</h1>
<div className="mt-3 h-[3px] w-16 rounded-full bg-[#f5a400]" />
<div className="mt-7 rounded-3xl bg-white px-5 py-6 shadow-[0_18px_42px_rgba(17,24,39,0.06)] sm:px-8 lg:px-10">
<div className="rounded-[24px] border border-[#e5edf8] bg-[#f8fbff] px-5 py-5">
<p className="text-sm font-semibold uppercase tracking-[0.18em] text-[#2450b5]">
1. Yêu cầu đối với Thương nhân
</p>
<div className="mt-4 space-y-3 text-[16px] leading-8 text-[#5f6f86]">
{REQUIREMENTS.map((item) => (
<div key={item} className="flex items-start gap-3">
<span className="mt-3 h-2 w-2 shrink-0 rounded-full bg-[#f5a400]" />
<span>{item}</span>
</div>
))}
</div>
</div>
<div className="mt-8">
<div className="flex items-center gap-3">
<div className="h-11 w-11 rounded-2xl bg-[#eff4ff] text-[#2450b5] flex items-center justify-center">
<FileCheck2 className="h-5 w-5" />
</div>
<div>
<p className="text-sm font-semibold uppercase tracking-[0.18em] text-[#2450b5]">
2. Quy trình thực hiện
</p>
<h2 className="mt-1 text-[24px] font-bold leading-tight text-[#1f2a44]">
Các bước xử lý thống nhất
</h2>
</div>
</div>
<div className="mt-6 space-y-4">
{STEPS.map((step, index) => {
const Icon = step.icon;
return (
<article
key={step.title}
className="rounded-[24px] border border-[#edf1f6] bg-white px-5 py-5 shadow-[0_14px_34px_rgba(17,24,39,0.06)]"
>
<div className="flex items-start gap-4">
<div className="inline-flex h-11 w-11 shrink-0 items-center justify-center rounded-2xl bg-[#eff4ff] text-[#2450b5]">
<Icon className="h-5 w-5" />
</div>
<div className="min-w-0 flex-1">
<div className="flex items-center gap-3">
<span className="inline-flex h-7 min-w-7 items-center justify-center rounded-full bg-[#2450b5] px-2 text-sm font-bold text-white">
{index + 1}
</span>
<h3 className="text-[20px] font-bold leading-tight text-[#1f2a44]">{step.title}</h3>
</div>
<p className="mt-3 text-[16px] leading-8 text-[#5f6f86]">{step.description}</p>
</div>
</div>
</article>
);
})}
</div>
</div>
<div className="mt-8 rounded-[24px] border border-[#dbe7ff] bg-[#f8fbff] px-5 py-5">
<div className="flex items-center gap-3 text-[#2450b5]">
<Clock3 className="h-5 w-5" />
<p className="text-sm font-semibold uppercase tracking-[0.18em]">3. Thời gian xử lý</p>
</div>
<p className="mt-4 text-[16px] leading-8 text-[#5f6f86]">
Trường hợp hồ sơ chưa hợp lệ, VCCI sẽ thông báo qua Hệ thống COVCCI các nội dung cần sửa đổi, bổ sung cho Thương nhân trong thời hạn 03 ngày làm việc kể từ ngày tiếp nhận hồ sơ. Thời gian xử lý cho một bộ hồ sơ hợp lệ là không quá 08 giờ làm việc kể từ thời điểm VCCI nhận đủ hồ sơ hợp lệ. Đối với trường hợp cần thẩm tra, xác minh hay trao đổi nội bộ và từ cơ quan chức năng trong và ngoài nước khác, thời gian giải quyết có thể kéo dài hơn so với quy định chung.
</p>
</div>
</div>
</div>
<aside className="space-y-5 lg:sticky lg:top-24">
<div className="rounded-[28px] border border-[#edf1f6] bg-[#fbfcff] px-6 py-6 shadow-[0_18px_42px_rgba(17,24,39,0.05)]">
<h2 className="text-[28px] font-bold leading-tight text-[#1f2a44]">Mốc thời gian</h2>
<div className="mt-5 space-y-4 text-[16px] leading-7 text-[#5f6f86]">
<div className="flex items-start gap-3">
<span className="mt-2 h-2.5 w-2.5 shrink-0 rounded-full bg-[#2f6ce5]" />
<span>Thông báo bổ sung: trong 03 ngày làm việc</span>
</div>
<div className="flex items-start gap-3">
<span className="mt-2 h-2.5 w-2.5 shrink-0 rounded-full bg-[#2f6ce5]" />
<span>Xử lý hồ sơ hợp lệ: không quá 08 giờ làm việc</span>
</div>
</div>
</div>
<div className="rounded-[28px] bg-linear-to-br from-[#1d56b7] to-[#21467f] px-6 py-6 text-white shadow-[0_22px_46px_rgba(28,52,120,0.18)]">
<h2 className="text-[26px] font-bold leading-tight">Kênh xử lý</h2>
<div className="mt-5 space-y-4 text-[15px] leading-7 text-white/88">
<p>Hệ thống COVCCI dùng để khai báo, tiếp nhận và theo dõi hồ sơ trực tuyến.</p>
<p>Thương nhân cần chuẩn bị đầy đủ hồ sơ điện tử, chữ ký số và hồ sơ giấy theo quy định.</p>
</div>
</div>
</aside>
</div>
</section>
);
}
'use client';
import { useParams } from "next/navigation";
import type { DynamicCategoryRouteItem, DynamicPostItem } from "../../types";
import ContactPage from "./ContactPage";
import CertificateTradeDocumentPage from "./CertificateTradeDocumentPage";
import FeesPage from "./FeesPage";
import FormsPage from "./FormsPage";
import LocationsPage from "./LocationsPage";
import PhapChePage from "./PhapChePage";
import ProcedurePage from "./ProcedurePage";
type LegalTradeRouterProps = {
post: DynamicPostItem;
category: DynamicCategoryRouteItem;
};
function resolveVariant(post: DynamicPostItem, category: DynamicCategoryRouteItem) {
const url = category.url || post.external_link;
const slug = category.slug || post.slug;
const externalLink = post.external_link;
if (
slug === "phap-che" ||
url === "/phap-che-cap-giay-chung-nhan-va-xac-nhan-chung-tu-thuong-mai/phap-che"
) {
return "phap-che" as const;
}
if (
slug === "giay-chung-nhan-gcn-va-chung-tu-thuong-mai-cttm" ||
url ===
"/phap-che-cap-giay-chung-nhan-va-xac-nhan-chung-tu-thuong-mai/giay-chung-nhan-gcn-va-chung-tu-thuong-mai-cttm"
) {
return "certificate-trade-document" as const;
}
if (
slug === "quy-trinh-tiep-nhan-ho-so-cap-gcn-va-xac-nhan-cttm" ||
slug === "thu-tuc-cap-co" ||
url ===
"/phap-che-cap-giay-chung-nhan-va-xac-nhan-chung-tu-thuong-mai/quy-trinh-tiep-nhan-ho-so-cap-gcn-va-xac-nhan-cttm" ||
url === "/xuat-xu-hang-hoa/thu-tuc-cap-co"
) {
return "procedure" as const;
}
if (slug === "bieu-mau-co-va-cach-khai" || url === "/xuat-xu-hang-hoa/bieu-mau-co-va-cach-khai") {
return "forms" as const;
}
if (
slug === "bieu-mau-gcn-va-noi-dung-khai-bao-gcn-cttm" ||
externalLink ===
"/phap-che-cap-giay-chung-nhan-va-xac-nhan-chung-tu-thuong-mai/bieu-mau-gcn-va-noi-dung-khai-bao-gcn-cttm" ||
url ===
"/phap-che-cap-giay-chung-nhan-va-xac-nhan-chung-tu-thuong-mai/bieu-mau-gcn-va-noi-dung-khai-bao-gcn-cttm"
) {
return "forms" as const;
}
if (
slug === "phi-cap-gcn-va-xac-nhan-cttm" ||
slug === "phi-va-le-phi-cap-co" ||
externalLink ===
"/phap-che-cap-giay-chung-nhan-va-xac-nhan-chung-tu-thuong-mai/phi-cap-gcn-va-xac-nhan-cttm" ||
url ===
"/phap-che-cap-giay-chung-nhan-va-xac-nhan-chung-tu-thuong-mai/phi-cap-gcn-va-xac-nhan-cttm" ||
url === "/xuat-xu-hang-hoa/phi-va-le-phi-cap-co"
) {
return "fees" as const;
}
if (
slug === "diem-cap-va-cap-gcn-va-xac-nhan-cttm" ||
slug === "diem-cap-va-thoi-gian-cap-co" ||
externalLink ===
"/phap-che-cap-giay-chung-nhan-va-xac-nhan-chung-tu-thuong-mai/diem-cap-va-cap-gcn-va-xac-nhan-cttm" ||
url ===
"/phap-che-cap-giay-chung-nhan-va-xac-nhan-chung-tu-thuong-mai/diem-cap-va-cap-gcn-va-xac-nhan-cttm" ||
url === "/xuat-xu-hang-hoa/diem-cap-va-thoi-gian-cap-co"
) {
return "locations" as const;
}
if (
slug === "thong-tin-lien-he" ||
slug === "thong-tin-lien-he-co" ||
externalLink ===
"/phap-che-cap-giay-chung-nhan-va-xac-nhan-chung-tu-thuong-mai/thong-tin-lien-he" ||
url ===
"/phap-che-cap-giay-chung-nhan-va-xac-nhan-chung-tu-thuong-mai/thong-tin-lien-he" ||
url === "/xuat-xu-hang-hoa/thong-tin-lien-he-co"
) {
return "contact" as const;
}
return "overview" as const;
}
export default function LegalTradePages({ post, category }: LegalTradeRouterProps) {
const params = useParams();
const pathSegments = Array.isArray(params.slug) ? params.slug : [params.slug];
const currentSlug = pathSegments.at(-1) ?? "";
const variant = resolveVariant(
{
...post,
slug: currentSlug || post.slug,
external_link: `/${pathSegments.filter(Boolean).join("/")}` || post.external_link,
},
{
...category,
slug: currentSlug || category.slug,
url: `/${pathSegments.filter(Boolean).join("/")}` || category.url,
},
);
if (variant === "phap-che") {
return <PhapChePage post={post} category={category} />;
}
if (variant === "certificate-trade-document") {
return <CertificateTradeDocumentPage post={post} category={category} />;
}
if (variant === "procedure") {
return <ProcedurePage post={post} category={category} />;
}
if (variant === "forms") {
return <FormsPage post={post} category={category} />;
}
if (variant === "fees") {
return <FeesPage post={post} category={category} />;
}
if (variant === "locations") {
return <LocationsPage post={post} category={category} />;
}
if (variant === "contact") {
return <ContactPage post={post} category={category} />;
}
return <PhapChePage post={post} category={category} />;
}
import type { DynamicCategoryRouteItem, DynamicPostItem } from "../../types";
export type LegalTradePageProps = {
post: DynamicPostItem;
category: DynamicCategoryRouteItem;
};
export type LegalTradeSection = {
title: string;
description?: string;
bullets?: string[];
numbered?: string[];
};
export type LegalTradeTemplate = {
pageTitle: string;
intro?: string;
sections: LegalTradeSection[];
sideCard?: {
title: string;
items: string[];
};
};
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment