Commit 32cb6417 authored by Phạm Quang Bảo's avatar Phạm Quang Bảo

fix/dynamic_page and route

parent 638751c0
......@@ -15,6 +15,12 @@ const nextConfig: NextConfig = {
port: "",
pathname: "/wp-content/uploads/**",
},
{
protocol: "http",
hostname: "103.72.98.149",
port: "7041",
pathname: "/images/**",
},
],
},
};
......
......@@ -44,8 +44,8 @@ const orvalConfig = async () => {
usePrefetch: true,
// useSuspenseQuery: true,
options: {
retry: 3,
retryDelay: 1000,
retry: 2,
retryDelay: 500,
}
},
mutator: {
......
......@@ -17,16 +17,16 @@ const Banner = () => {
slidesPerView={1}
onSwiper={(s) => (swiperRef.current = s)}
>
<SwiperSlide>
{/* <SwiperSlide>
<ImageNext
src="https://vcci-hcm.org.vn/wp-content/uploads/2025/10/1.1.-Hero-Banner-CEO-2025-Bi-Sai-Nam-2025-Nhe-2560x720-Px.jpg.webp"
src="/1.png"
alt="Banner"
width={2560}
height={720}
sizes="100vw"
className="w-full h-[200px] sm:h-[300px] md:h-[400px] lg:h-[500px] object-cover"
/>
</SwiperSlide>
</SwiperSlide> */}
<SwiperSlide>
<ImageNext
src="https://vcci-hcm.org.vn/wp-content/uploads/2022/07/Landscape-HCM_3-01.png"
......
......@@ -11,7 +11,7 @@ const EventsCalendar = () => {
Lịch sự kiện
</h2>
<Link
href="/hoat-dong/su-kien"
href="#"
className="text-[#e8c518] hover:underline text-sm sm:text-base"
>
<ChevronsRight />
......
......@@ -27,7 +27,7 @@ const Members = () => {
Hội viên tiêu biểu
</h2>
<Link
href="/danh-ba-hoi-vien"
href="#"
className="text-[#063e8e] hover:underline text-sm font-medium"
>
<ChevronsRight />
......@@ -43,9 +43,9 @@ const Members = () => {
slidesPerView={6}
spaceBetween={16}
breakpoints={{
0: { slidesPerView: 2, spaceBetween: 10 },
640: { slidesPerView: 3, spaceBetween: 16 },
1024: { slidesPerView: 3, spaceBetween: 24 },
0: { slidesPerView: 3, spaceBetween: 10 },
640: { slidesPerView: 4, spaceBetween: 16 },
1024: { slidesPerView: 6, spaceBetween: 24 },
}}
className="partner-swiper"
>
......
......@@ -14,7 +14,7 @@ function QuickLinks() {
<div>
<Link
className="text-[#363636]"
href="https://vcci-hcm.org.vn/lien-ket-nhanh/cam-nang-huong-dan-dau-tu-kinh-doanh-tai-viet-nam-2023/"
href="#"
>
🔗 Cẩm nang hướng dẫn đầu tư kinh doanh tại Việt Nam
</Link>
......@@ -22,7 +22,7 @@ function QuickLinks() {
<div>
<Link
className="text-[#363636]"
href="https://vcci-hcm.org.vn/lien-ket-nhanh/doanh-nghiep-kien-nghi-ve-chinh-sach-va-phap-luat/"
href="#"
>
🔗 Doanh nghiệp kiến nghị về chính sách và pháp luật
</Link>
......
......@@ -29,12 +29,12 @@ const VideoAndPartners = () => {
<div className="flex flex-col md:flex-row gap-4 md:gap-6">
{[
{
src: "https://www.youtube.com/embed/J0Iz0iGuAXY",
title: "VCCI-HCM 2024 IN REVIEW (ENGLISH VERSION)",
src: "https://www.youtube.com/embed/U35yP_yH1dA",
title: "Chào mừng đến với MeU Solutions – Biến giấc mơ chuyển đổi số của Daonh nghiệp bạn thành hiện thực 🚀",
},
{
src: "https://www.youtube.com/embed/_OnnGWv2ehM",
title: "Hội nghị Hội viên VCCI - Gala Mừng Xuân Ất Tỵ 2025",
src: "https://www.youtube.com/embed/yQaLiPMemcg",
title: "MEU SOLUTIONS - 9 Năm Đồng Hành Cùng Công Nghệ Việt",
},
].map((video, i) => (
<div key={i} className="w-full md:w-1/2">
......@@ -76,9 +76,9 @@ const VideoAndPartners = () => {
slidesPerView={3}
spaceBetween={16}
breakpoints={{
0: { slidesPerView: 3, spaceBetween: 10, grid: { rows: 1 } },
640: { slidesPerView: 3, spaceBetween: 16 },
1024: { slidesPerView: 3, spaceBetween: 24 },
0: { slidesPerView: 3, spaceBetween: 10, grid: { rows: 2 } },
640: { slidesPerView: 3, spaceBetween: 16, grid: { rows: 2 } },
1024: { slidesPerView: 3, spaceBetween: 24, grid: { rows: 2 } },
}}
className="partner-swiper"
>
......
......@@ -21,7 +21,7 @@ const Page = () => {
{/* contents */}
<div className="container mx-auto px-3 sm:px-6 lg:px-10 space-y-12">
<FeaturedNews />
<div>
{/* <div>
<Link href="https://hardwaretools.com.vn/">
<ImageNext
src="/home/Standard-Banner-1-2024.png.webp"
......@@ -30,7 +30,7 @@ const Page = () => {
height={720}
/>
</Link>
</div>
</div> */}
<section className="flex flex-col lg:flex-row gap-5 pb-10 mb-0">
<News />
......
......@@ -3,7 +3,7 @@
import { notFound, useParams } from "next/navigation";
import { useGetNewsPageConfigGetHierarchical } from "@/api/endpoints/news-page-config";
import { GetNewsPageConfigResponseType } from "@/api/types/news-page-config";
import { GetNewsResponseType, NewsResponseData } from "@/api/types/news";
import { GetNewsResponseType } from "@/api/types/news";
// templates
import InformationPage from "./templates/InformationPage";
......@@ -16,19 +16,17 @@ export default function DynamicPage() {
const params = useParams();
const slug = Array.isArray(params.slug) ? params.slug : [params.slug];
const path = slug.join("/");
const lastThree = slug.slice(-3).join('/');
// query
const { data: category, isLoading, isError } = useGetNewsPageConfigGetHierarchical<GetNewsPageConfigResponseType>({
const { data: news } = useGetNews<GetNewsResponseType>(
{ filters: `external_link==/${path}` }
);
const { data: category, isLoading: categoryLoading, isError } = useGetNewsPageConfigGetHierarchical<GetNewsPageConfigResponseType>({
static_link: `/${path}`,
});
const data = useGetNews<GetNewsResponseType>(
{ filters: `external_link==/${lastThree}` }
);
// const children = category?.responseData?.children || [];
// // redirect to first child if has children
// const children = category?.responseData?.children || [];
// useEffect(() => {
// if (!category) return;
// if (slug.length === 1 && children.length > 0) {
......@@ -40,23 +38,27 @@ export default function DynamicPage() {
// }, [slug, category, children, router]);
//template
// if (isLoading) {
// return (
// <div className="flex justify-center items-center w-full h-64">
// <Spinner />
// </div>
// );
// }
// not found page
// if (isError) {
// return notFound();
// }
// default
return (data?.data?.responseData?.rows.length !== 0 ? <ArticleDetailPage /> : (
category?.responseData?.is_article ?
<ArticlePage isError={isError} isLoading={isLoading} /> :
<InformationPage isError={isError} isLoading={isLoading} />
));
if (news?.responseData?.count == 0 && categoryLoading) {
return (
<div className="flex justify-center items-center w-full h-64">
<Spinner />
</div>
);
}
if (news && news?.responseData.rows.length !== 0) {
return <ArticleDetailPage data={news} />;
}
else if (category?.responseData.is_article == true) {
return <ArticlePage />;
}
else if (category?.responseData.is_article == false) {
return <InformationPage />;
}
else if (isError) {
return notFound();
}
}
......@@ -4,64 +4,53 @@ import { GetNewsPageConfigResponseType } from "@/api/types/news-page-config";
import { useGetNewsPageConfigGetHierarchical } from "@/api/endpoints/news-page-config";
import ListCategory from "@/components/base/list-category";
import { useParams } from "next/dist/client/components/navigation";
import { useGetNews } from "@/api/endpoints/news";
import { GetNewsResponseType } from "@/api/types/news";
import EventCalendar from "@/components/base/event-calendar";
import dayjs from "dayjs";
import parse from "html-react-parser";
import { Spinner } from "@/components/ui";
import { notFound } from "next/navigation";
export default function ArticleDetailPage() {
// get url
export default function ArticleDetailPage({ data }: { data: GetNewsResponseType }) {
const params = useParams();
const slug = Array.isArray(params.slug) ? params.slug : [params.slug];
const path = slug.join("/");
//query
const { data: categoriesPage } = useGetNewsPageConfigGetHierarchical<GetNewsPageConfigResponseType>({
const { data: category } = useGetNewsPageConfigGetHierarchical<GetNewsPageConfigResponseType>({
code: slug[0],
});
const { data, isLoading } = useGetNews<GetNewsResponseType>({
filters: `external_link==/${path}`,
});
const children = category?.responseData?.children ?? [];
// template
if (!isLoading && (!data?.responseData?.rows || data.responseData.rows.length === 0)) {
return notFound();
}
return (
<div className='container w-full flex justify-center items-center pb-10'>
{isLoading ? (
<div className='flex justify-center items-center w-full h-64'>
<Spinner />
</div>
) : (
<div className='flex flex-col gap-5 w-full'>
<ListCategory categories={categoriesPage?.responseData?.children} />
<div className="grid grid-cols-1 lg:grid-cols-3 gap-5">
<main className="lg:col-span-2 bg-white border rounded-md p-8">
<div className='pb-5 text-primary text-2xl leading-normal font-medium'>
{data?.responseData?.rows[0]?.title}
</div>
<div className='flex items-center gap-2 text-sm mb-4'>
<span className='text-base text-blue-700'>
{dayjs(data?.responseData?.rows[0]?.created_at).format('DD/MM/YYYY')}
</span>
</div>
<hr className="my-5" />
<div className='flex-1 text-app-grey text-base overflow-hidden'>
<div className="prose tiptap overflow-hidden">
{parse(data?.responseData?.rows[0]?.description ?? '')}
</div>
<div className='flex flex-col gap-5 w-full'>
{children.length !== 0 ? (
<ListCategory categories={children} />
) : (
<br />
)}
<div className="grid grid-cols-1 lg:grid-cols-3 gap-5">
<main className="lg:col-span-2 bg-white border rounded-md p-8">
<div className='pb-5 text-primary text-2xl leading-normal font-medium'>
{data?.responseData?.rows[0]?.title}
</div>
<div className='flex items-center gap-2 text-sm mb-4'>
<span className='text-base text-blue-700'>
{dayjs(data?.responseData?.rows[0]?.created_at).format('DD/MM/YYYY')}
</span>
</div>
<hr className="my-5" />
<div className='flex-1 text-app-grey text-base overflow-hidden'>
<div className="prose tiptap overflow-hidden">
{parse(data?.responseData?.rows[0]?.description ?? '')}
</div>
</main>
<aside className="space-y-6">
<EventCalendar />
</aside>
</div>
</div>
</main>
<aside className="space-y-6">
<EventCalendar />
</aside>
</div>
)}
</div>
</div>
);
}
\ No newline at end of file
......@@ -3,7 +3,7 @@
import { GetNewsPageConfigResponseType } from "@/api/types/news-page-config";
import { useGetNewsPageConfigGetHierarchical } from "@/api/endpoints/news-page-config";
import ListCategory from "@/components/base/list-category";
import { useParams, useSearchParams, useRouter, usePathname, notFound } from "next/navigation";
import { useParams, useSearchParams, useRouter, usePathname } from "next/navigation";
import { useGetNews } from "@/api/endpoints/news";
import { GetNewsResponseType } from "@/api/types/news";
import CardNews from "@/components/base/card-news";
......@@ -13,7 +13,7 @@ import EventCalendar from "@/components/base/event-calendar";
import { useState, useEffect } from "react";
import { Spinner } from "@/components/ui";
export default function ArticlePage({ isError, isLoading }: { isError: boolean, isLoading: boolean }) {
export default function ArticlePage() {
// get url
const params = useParams();
const slug = Array.isArray(params.slug) ? params.slug : [params.slug];
......@@ -41,7 +41,7 @@ export default function ArticlePage({ isError, isLoading }: { isError: boolean,
}, [page]);
// query
const { data: categoriesPage } = useGetNewsPageConfigGetHierarchical<GetNewsPageConfigResponseType>({
const { data: category } = useGetNewsPageConfigGetHierarchical<GetNewsPageConfigResponseType>({
code: slug[0],
});
......@@ -51,14 +51,8 @@ export default function ArticlePage({ isError, isLoading }: { isError: boolean,
currentPage: String(page),
});
const children = category?.responseData?.children ?? [];
//template
if (isLoading) return (
<div className="flex justify-center items-center w-full h-64">
<Spinner />
</div>
);
if (isError) return notFound();
return (
<div className="min-h-screen container mx-auto">
{articlesLoading ? (
......@@ -67,7 +61,11 @@ export default function ArticlePage({ isError, isLoading }: { isError: boolean,
</div>
) : (
<div className="w-full flex flex-col gap-5">
<ListCategory categories={categoriesPage?.responseData?.children} />
{children.length !== 0 ? (
<ListCategory categories={children} />
) : (
<br />
)}
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
<main className="lg:col-span-2 bg-background">
<div className="pb-5 overflow-hidden">
......
......@@ -8,16 +8,15 @@ import { Spinner } from "@/components/ui/spinner";
import { GetNewsResponseType } from "@/api/types/news";
import { useGetNews } from "@/api/endpoints/news";
import parse from "html-react-parser";
import { notFound } from "next/navigation";
export default function InformationPage({ isError, isLoading }: { isError: boolean, isLoading: boolean }) {
export default function InformationPage() {
// get url
const params = useParams();
const slug = Array.isArray(params.slug) ? params.slug : [params.slug];
const path = slug.join("/");
// query
const { data: categoryPage } = useGetNewsPageConfigGetHierarchical<GetNewsPageConfigResponseType>({
const { data: category } = useGetNewsPageConfigGetHierarchical<GetNewsPageConfigResponseType>({
static_link: `/${slug[0]}`,
});
......@@ -25,14 +24,8 @@ export default function InformationPage({ isError, isLoading }: { isError: boole
filters: `page_config.static_link==/${path}`,
});
const children = category?.responseData?.children ?? [];
//template
if (isLoading) return (
<div className="flex justify-center items-center w-full h-64">
<Spinner />
</div>
);
if (isError) return notFound();
return (
<div className='container w-full flex justify-center items-center pb-10'>
{informationLoading ? (
......@@ -41,7 +34,11 @@ export default function InformationPage({ isError, isLoading }: { isError: boole
</div>
) : (
<div className='flex flex-col gap-5 w-full'>
<ListCategory categories={categoryPage?.responseData?.children} />
{children.length !== 0 ? (
<ListCategory categories={children} />
) : (
<br />
)}
<main className=" bg-white border rounded-md py-10 px-5 md:px-20 lg:px-20">
<div className='text-primary text-2xl leading-normal font-bold'>
{information?.responseData?.rows[0]?.title}
......
......@@ -111,23 +111,22 @@ function Footer() {
</h2>
<div className="h-0.5 w-14 bg-[#063e8e] mx-0"></div>
<div className="w-full overflow-hidden rounded-md">
<iframe
className="w-full sm:h-[140px]"
src="https://www.facebook.com/plugins/page.php?href=https%3A%2F%2Fwww.facebook.com%2FVCCIHCMC%3Fref%3Dembed_page&tabs=&width=340&height=130&small_header=false&adapt_container_width=true&hide_cover=false&show_facepile=false"
style={{ border: "none", overflow: "hidden" }}
scrolling="no"
frameBorder="0"
<iframe src="https://www.facebook.com/plugins/page.php?href=https%3A%2F%2Fwww.facebook.com%2Fmeusolutions&tabs&width=340&height=130&small_header=false&adapt_container_width=true&hide_cover=false&show_facepile=true&appId"
width="340"
height="130"
className="border:none;overflow:hidden"
scrolling="no" frameBorder="0"
allowFullScreen={true}
allow="autoplay; clipboard-write; encrypted-media; picture-in-picture; web-share"
></iframe>
allow="autoplay; clipboard-write; encrypted-media; picture-in-picture; web-share">
</iframe>
</div>
<div className="flex gap-3 justify-start">
{[
{ icon: <Facebook size={20} />, link: "https://www.facebook.com/VCCIHCMC/" },
{ icon: <Twitter size={20} />, link: "https://twitter.com/VCCI_HCM" },
{ icon: <Youtube size={20} />, link: "https://www.youtube.com/user/VCCIHCMC" },
{ icon: <Linkedin size={20} />, link: "https://www.linkedin.com/company/vietnam-chamber-of-commerce-and-industry-ho-chi-minh-city-branch-vcci-hcm-?trk=biz-companies-cym" },
{ icon: <Facebook size={20} />, link: "#" },
{ icon: <Twitter size={20} />, link: "#" },
{ icon: <Youtube size={20} />, link: "#" },
{ icon: <Linkedin size={20} />, link: "#" },
].map((s, i) => (
<a
key={i}
......
......@@ -30,13 +30,13 @@ function Header() {
</div>
<Link
className="px-3 py-2 text-[14px] text-white hover:opacity-80"
href="/site-map"
href="#"
>
Sitemap
</Link>
<Link
className="px-3 py-2 text-[14px] text-white hover:opacity-80"
href="https://vccihcm.vn/lien-he"
href="/lien-he"
>
Liên hệ
</Link>
......@@ -58,28 +58,28 @@ function Header() {
/>
<div className="flex gap-2">
<a
href="https://www.facebook.com/VCCIHCMC/"
href="#"
target="_blank"
className="bg-white size-7 rounded-full flex items-center justify-center text-[#063e8e] hover:opacity-80 transition"
>
<Facebook size={16} />
</a>
<a
href="https://twitter.com/VCCI_HCM"
href="#"
target="_blank"
className="bg-white size-7 rounded-full flex items-center justify-center text-[#063e8e] hover:opacity-80 transition"
>
<Twitter size={16} />
</a>
<a
href="https://www.youtube.com/user/VCCIHCMC"
href="#"
target="_blank"
className="bg-white size-7 rounded-full flex items-center justify-center text-[#063e8e] hover:opacity-80 transition"
>
<Youtube size={16} />
</a>
<a
href="https://www.linkedin.com/company/vietnam-chamber-of-commerce-and-industry-ho-chi-minh-city-branch-vcci-hcm-?trk=biz-companies-cym"
href="#"
target="_blank"
className="bg-white size-7 rounded-full flex items-center justify-center text-[#063e8e] hover:opacity-80 transition"
>
......
const links = {
analyticsGoogle: 'G-C9TEK9BS4C',
apiEndpoint: `https://hiea.meu-solutions.com/api/v1.0`,
imageEndpoint: `https://hiea.meu-solutions.com`,
imageEndpoint: `http://103.72.98.149:7041`,
siteURL: 'https://hiea-news.meu-solutions.com',
}
export default links
export default links
\ No newline at end of file
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