Commit 0fb38eab authored by Vũ Đình Nguyên's avatar Vũ Đình Nguyên

update final

parent 11407099
import type { NextConfig } from "next";
import links from "./src/links/index";
const nextConfig: NextConfig = {
/* config options here */
images: {
remotePatterns: [
{
protocol: "https",
hostname: links.backendHost,
port: "",
pathname: "/vcci/images/**",
},
],
},
};
export default nextConfig;
......@@ -329,6 +329,10 @@ const Page = () => {
src={`${BASE_URL.imageEndpoint}${event.image}`}
alt={event.name}
className="w-full h-full object-cover"
onError={(e) => {
(e.target as HTMLImageElement).src =
"/img-error.png";
}}
/>
</div>
......
......@@ -7,6 +7,7 @@ import ListFilter from "../../components/list-filter";
import { useGetNewsId } from '@/api/endpoints/news';
import parse from "html-react-parser";
import { useParams } from 'next/navigation'
import EventCalendar from '@/components/base/event-calendar'
import { GetNewsDetailResponseType } from '@lib/types/news-detail-response-data';
// ...existing code...
const Page: React.FC = () => {
......@@ -29,7 +30,7 @@ const Page: React.FC = () => {
{/* Sidebar */}
<aside className="space-y-6">
<ListFilter />
<EventCalendar />
<div className="bg-white border rounded-md overflow-hidden">
<div className="w-full h-56 relative bg-gray-100">
......
......@@ -11,15 +11,14 @@ import { GetNewsResponseType } from "@api/types/NewsPage.type";
import { PATHS } from "@constants/paths";
import { Spinner } from "@components/ui/spinner";
export default function Page() {
const [submitSearch] = useState("");
const [submitSearch,setsubmitSearch] = useState("");
const [page, setPage] = useState(1);
const pageSize = 5;
const { data: allData,isLoading } = useGetNews<GetNewsResponseType>({
pageSize: String(pageSize),
currentPage: String(page),
// filters: submitSearch ? `title @=${submitSearch}` : undefined,
filters:'category@=Chủ đề'
filters: submitSearch ? `title @=${submitSearch},category@=Chủ đề` : 'category@=Chủ đề',
});
return (
<div className="min-h-screen container mx-auto p-4">
......@@ -37,26 +36,32 @@ export default function Page() {
</div>
) : (
<>
{allData?.responseData.rows.map((news) => (
<NewsContent key={news.id} news={news} link={`${PATHS.ownerRepresentatives}/chu-de/${news.id}`}/>
))}
{(!allData || (allData.responseData.rows || []).length === 0) ? (
<div className="py-12 text-center text-gray-600">Không có dữ liệu</div>
) : (
<>
{allData.responseData.rows.map((news) => (
<NewsContent key={news.id} news={news} link={`${PATHS.ownerRepresentatives}/chu-de/${news.id}`}/>
))}
<div className="w-full flex justify-center mt-4">
<Pagination
pageCount={Number(allData?.responseData.totalPages ?? 1)}
page={Number(allData?.responseData.currentPage ?? page)}
onChangePage={(p) => setPage(p)}
onGoToPreviousPage={() => setPage(Math.max(1, page - 1))}
onGoToNextPage={() =>
setPage(
Math.min(
Number(allData?.responseData.totalPages ?? 1),
page + 1
)
)
}
/>
</div>
<div className="w-full flex justify-center mt-4">
<Pagination
pageCount={Number(allData?.responseData.totalPages ?? 1)}
page={Number(allData?.responseData.currentPage ?? page)}
onChangePage={(p) => setPage(p)}
onGoToPreviousPage={() => setPage(Math.max(1, page - 1))}
onGoToNextPage={() =>
setPage(
Math.min(
Number(allData?.responseData.totalPages ?? 1),
page + 1
)
)
}
/>
</div>
</>
)}
</>
)}
</div>
......@@ -64,7 +69,7 @@ export default function Page() {
{/* Sidebar */}
<aside className="space-y-6">
<ListFilter />
<ListFilter onSearch={setsubmitSearch}/>
<div className="bg-white border rounded-md overflow-hidden">
<div className="w-full h-56 relative bg-gray-100">
......
......@@ -8,6 +8,7 @@ import { useGetNewsId } from '@/api/endpoints/news';
import parse from "html-react-parser";
import { useParams } from 'next/navigation'
import { GetNewsDetailResponseType } from '@lib/types/news-detail-response-data';
import EventCalendar from '@/components/base/event-calendar'
// ...existing code...
const Page: React.FC = () => {
const { id } = useParams()
......@@ -29,7 +30,7 @@ const Page: React.FC = () => {
{/* Sidebar */}
<aside className="space-y-6">
<ListFilter />
<EventCalendar />
<div className="bg-white border rounded-md overflow-hidden">
<div className="w-full h-56 relative bg-gray-100">
......
......@@ -11,7 +11,7 @@ import { GetNewsResponseType } from "@api/types/NewsPage.type";
import { PATHS } from "@constants/paths";
import { Spinner } from "@components/ui/spinner";
export default function Page() {
const [submitSearch] = useState("");
const [submitSearch,setsubmitSearch] = useState("");
const [page, setPage] = useState(1);
const pageSize = 5;
......@@ -63,7 +63,7 @@ export default function Page() {
{/* Sidebar */}
<aside className="space-y-6">
<ListFilter />
<ListFilter onSearch={setsubmitSearch}/>
<div className="bg-white border rounded-md overflow-hidden">
<div className="w-full h-56 relative bg-gray-100">
......
......@@ -8,6 +8,7 @@ import { useGetNewsId } from "@/api/endpoints/news";
import parse from "html-react-parser";
import { useParams } from "next/navigation";
import { GetNewsDetailResponseType } from "@lib/types/news-detail-response-data";
import EventCalendar from '@/components/base/event-calendar'
// ...existing code...
const Page: React.FC = () => {
const { id } = useParams();
......@@ -33,7 +34,7 @@ const Page: React.FC = () => {
{/* Sidebar */}
<aside className="space-y-6">
<ListFilter />
<EventCalendar />
<div className="bg-white border rounded-md overflow-hidden">
<div className="w-full h-56 relative bg-gray-100">
......
......@@ -36,19 +36,25 @@ export default function Page() {
</div>
) : (
<>
{allData?.responseData.rows.map((news) => (
<NewsContent key={news.id} news={news} link={`${PATHS.ownerRepresentatives}/tin-lien-quan/${news.id}`} />
))}
{(!allData || (allData.responseData.rows || []).length === 0) ? (
<div className="py-12 text-center text-gray-600">Không có dữ liệu</div>
) : (
<>
{allData.responseData.rows.map((news) => (
<NewsContent key={news.id} news={news} link={`${PATHS.ownerRepresentatives}/tin-lien-quan/${news.id}`} />
))}
<div className="w-full flex justify-center mt-4">
<Pagination
pageCount={Number(allData?.responseData.totalPages ?? 1)}
page={Number(allData?.responseData.currentPage ?? page)}
onChangePage={(p) => setPage(p)}
onGoToPreviousPage={() => setPage(Math.max(1, page - 1))}
onGoToNextPage={() => setPage(Math.min(Number(allData?.responseData.totalPages ?? 1), page + 1))}
/>
</div>
<div className="w-full flex justify-center mt-4">
<Pagination
pageCount={Number(allData?.responseData.totalPages ?? 1)}
page={Number(allData?.responseData.currentPage ?? page)}
onChangePage={(p) => setPage(p)}
onGoToPreviousPage={() => setPage(Math.max(1, page - 1))}
onGoToNextPage={() => setPage(Math.min(Number(allData?.responseData.totalPages ?? 1), page + 1))}
/>
</div>
</>
)}
</>
)}
</div>
......
......@@ -8,6 +8,7 @@ import { useGetNewsId } from '@/api/endpoints/news';
import parse from "html-react-parser";
import { useParams } from 'next/navigation'
import { GetNewsDetailResponseType } from '@lib/types/news-detail-response-data';
import EventCalendar from '@/components/base/event-calendar'
// ...existing code...
const Page: React.FC = () => {
const { id } = useParams()
......@@ -29,7 +30,7 @@ const Page: React.FC = () => {
{/* Sidebar */}
<aside className="space-y-6">
<ListFilter />
<EventCalendar />
<div className="bg-white border rounded-md overflow-hidden">
<div className="w-full h-56 relative bg-gray-100">
......
......@@ -13,12 +13,14 @@ import { Spinner } from "@components/ui/spinner";
export default function Page() {
const [submitSearch] = useState("");
const [page, setPage] = useState(1);
const [filtersString, setFiltersString] = useState<string | undefined>('')
const pageSize = 5;
const { data: allData, isLoading } = useGetNews<GetNewsResponseType>({
pageSize: String(pageSize),
currentPage: String(page),
filters: submitSearch ? `title @=${submitSearch}` : 'category @=Đào tạo',
filters: filtersString ? `${filtersString},category @=Đào tạo` : 'category @=Đào tạo',
});
return (
<div className="min-h-screen container mx-auto p-4">
......@@ -36,19 +38,25 @@ export default function Page() {
</div>
) : (
<>
{allData?.responseData.rows.map((news) => (
<NewsContent key={news.id} news={news} link={`${PATHS.event}/dao-tao/${news.id}`} />
))}
{(!allData || (allData.responseData.rows || []).length === 0) ? (
<div className="py-12 text-center text-gray-600">Không có dữ liệu</div>
) : (
<>
{allData.responseData.rows.map((news) => (
<NewsContent key={news.id} news={news} link={`${PATHS.event}/dao-tao/${news.id}`} />
))}
<div className="w-full flex justify-center mt-4">
<Pagination
pageCount={Number(allData?.responseData.totalPages ?? 1)}
page={Number(allData?.responseData.currentPage ?? page)}
onChangePage={(p) => setPage(p)}
onGoToPreviousPage={() => setPage(Math.max(1, page - 1))}
onGoToNextPage={() => setPage(Math.min(Number(allData?.responseData.totalPages ?? 1), page + 1))}
/>
</div>
<div className="w-full flex justify-center mt-4">
<Pagination
pageCount={Number(allData?.responseData.totalPages ?? 1)}
page={Number(allData?.responseData.currentPage ?? page)}
onChangePage={(p) => setPage(p)}
onGoToPreviousPage={() => setPage(Math.max(1, page - 1))}
onGoToNextPage={() => setPage(Math.min(Number(allData?.responseData.totalPages ?? 1), page + 1))}
/>
</div>
</>
)}
</>
)}
</div>
......@@ -56,7 +64,37 @@ export default function Page() {
{/* Sidebar */}
<aside className="space-y-6">
<EventFilter />
<EventFilter
onFilter={(payload) => {
const parts: string[] = []
// query
if (payload.query) parts.push(`title @=${payload.query}`)
const nowIso = new Date().toISOString()
// upcoming / past
if (payload.upcoming && !payload.past) {
parts.push(`created_at>=${nowIso}`)
} else if (payload.past && !payload.upcoming) {
parts.push(`created_at<=${nowIso}`)
}
if (payload.fromDate) {
const fromIso = new Date(payload.fromDate).toISOString()
parts.push(`created_at>=${fromIso}`)
}
if (payload.toDate) {
const toIso = new Date(payload.toDate).toISOString()
parts.push(`created_at<=${toIso}`)
}
const filters = parts.length > 0 ? parts.join(',') : undefined
setFiltersString(filters)
setPage(1)
}}
onReset={() => {
setFiltersString(undefined)
setPage(1)
}}
/>
<div className="bg-white border rounded-md overflow-hidden">
<div className="w-full h-56 relative bg-gray-100">
......
// Core
"use client";
import Image from "next/image";
import { useState } from "react";
import { Calendar, MapPin, CreditCard } from "lucide-react";
import ListCategory from "@app/dai-dien-gioi-chu/components/list-category";
import { EVENT_CATEGORIES } from "@constants/categories";
import ListFilter from "@app/dai-dien-gioi-chu/components/list-filter";
import {useGetEventsId} from '@/api/endpoints/event';
import { useGetEventsId } from "@/api/endpoints/event";
import parse from "html-react-parser";
import { useParams } from 'next/navigation'
import { GetNewsDetailResponseType } from '@lib/types/news-detail-response-data';
import {GetEventsIdQueryResponseType} from '@api/types/event';
import { useParams } from "next/navigation";
import { GetNewsDetailResponseType } from "@lib/types/news-detail-response-data";
import { GetEventsIdQueryResponseType } from "@api/types/event";
import { Spinner } from "@components/ui/spinner";
import Links from "@links/index";
import EventCalendar from '@/components/base/event-calendar'
// ...existing code...
const Page: React.FC = () => {
const { id } = useParams()
const { data, isLoading } = useGetEventsId<GetEventsIdQueryResponseType>(id as string)
const { id } = useParams();
const { data, isLoading } = useGetEventsId<GetEventsIdQueryResponseType>(
id as string
);
return (
<div className="min-h-screen w-full container mx-auto p-4">
<div className="w-full flex flex-col gap-5">
<ListCategory categories={EVENT_CATEGORIES} />
<ListCategory categories={EVENT_CATEGORIES} />
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
{/* Main content */}
<main className="lg:col-span-2 bg-white border rounded-md p-6">
{isLoading ? (
<div className="flex justify-center items-center py-12">
<Spinner className="size-8" />
<span className="ml-2 text-gray-600">Đang tải chi tiết sự kiện...</span>
<span className="ml-2 text-gray-600">
Đang tải chi tiết sự kiện...
</span>
</div>
) : (
<>
<div className='pb-5 text-primary text-2xl leading-normal font-medium'>
<div className="pb-5 text-primary text-2xl leading-normal font-medium">
{data?.responseData?.name}
</div>
<hr className="py-2"/>
<div className="p-7.5 prose tiptap overflow-hidden">{parse(data?.responseData?.description ?? '')}</div>
<hr className="py-2" />
{/* Top summary with image + details */}
<div className="flex flex-col lg:flex-row gap-6 my-6">
<div className="w-full lg:w-1/2 bg-gray-50 rounded-md overflow-hidden">
{data?.responseData?.image ? (
<div className="w-full h-52 relative ">
{/* Use controlled src state to avoid mutating Image DOM directly */}
{/* Next.js <Image> does not expose the underlying img element reliably in all builds */}
{/* so keep a React state for src and swap to a fallback on error. */}
<EventImage
src={`${Links.imageEndpoint}${data.responseData.image}`}
alt={data.responseData.name || "image"}
/>
</div>
) : (
<div className="w-full h-52 bg-gray-200" />
)}
</div>
<div className="w-full lg:w-1/2 bg-white border rounded-md p-6">
<div className="flex flex-col gap-3">
<div className="text-sm text-gray-500">
Hạn đăng kí:{" "}
<span className="text-gray-900 font-medium">
{data?.responseData?.created_at
? new Date(
data.responseData.created_at
).toLocaleDateString()
: "-"}
</span>
</div>
<div className="text-sm text-gray-500 flex items-start gap-2">
<Calendar className="h-5 w-5 text-yellow-500" />
<div>
<div className="text-sm font-medium text-gray-800">
Bắt đầu: {data?.responseData?.start_time
? new Date(
data.responseData.start_time
).toLocaleString()
: "-"}
</div>
<div className="text-sm font-medium text-gray-800">
Kết thúc: {data?.responseData?.end_time
? new Date(
data.responseData.end_time
).toLocaleString()
: "-"}
</div>
</div>
</div>
<div className="text-sm text-gray-500 flex items-center gap-2">
<MapPin className="h-5 w-5 text-blue-600" />
<div className="text-sm font-medium text-gray-800">
Địa điểm: {data?.responseData?.location ??
data?.responseData?.province ??
"-"}
</div>
</div>
<div className="text-sm text-gray-500 flex items-center gap-2">
<CreditCard className="h-5 w-5 text-yellow-400" />
<div className="text-sm font-medium text-gray-800">
Phí tham dự: {data?.responseData?.table_cost
? `${
data.responseData.table_count
} Bàn : ${data.responseData.table_cost.toLocaleString()} đ`
: "Vui lòng xem chi tiết trong bài"}
</div>
</div>
</div>
</div>
</div>
{/* Full description */}
<div className="p-7.5 prose tiptap overflow-hidden">
{parse(data?.responseData?.description ?? "")}
</div>
</>
)}
</main>
{/* Sidebar */}
<aside className="space-y-6">
<ListFilter />
<EventCalendar />
<div className="bg-white border rounded-md overflow-hidden">
<div className="w-full h-56 relative bg-gray-100">
......@@ -60,3 +145,25 @@ const Page: React.FC = () => {
};
export default Page;
// Local small component to safely handle Image src fallback without mutating DOM
type EventImageProps = {
src: string;
alt?: string;
};
function EventImage({ src, alt }: EventImageProps) {
const [imgSrc, setImgSrc] = useState<string>(src);
return (
<Image
src={imgSrc}
alt={alt ?? "image"}
fill
className="object-cover"
onError={() => {
// swap to local fallback file when Next/Image fails to load the provided URL
if (imgSrc !== "/img-error.png") setImgSrc("/img-error.png");
}}
/>
);
}
\ No newline at end of file
......@@ -64,7 +64,7 @@ export default function Page() {
onFilter={(payload) => {
const parts: string[] = []
// query
if (payload.query) parts.push(`title @=${payload.query}`)
if (payload.query) parts.push(`name @=${payload.query}`)
const nowIso = new Date().toISOString()
// upcoming / past
......
......@@ -10,14 +10,14 @@ import { GetNewsResponseType } from "@api/types/NewsPage.type";
import { Spinner } from "@components/ui/spinner";
export default function Page() {
const [submitSearch] = useState("");
const [submitSearch,setSubmitSearch] = useState("");
const [page, setPage] = useState(1);
const pageSize = 5;
const { data: allData, isLoading } = useGetNews<GetNewsResponseType>({
pageSize: String(pageSize),
currentPage: String(page),
filters: submitSearch ? `title @=${submitSearch}` : `category @=Kết nối hội viên`,
filters: submitSearch ? `title @=${submitSearch},category@=Kết nối hội viên` : `category@=Kết nối hội viên`,
});
return (
<div className="min-h-screen container mx-auto pb-4">
......@@ -32,9 +32,11 @@ export default function Page() {
<Spinner className="size-8" />
<span className="ml-2 text-gray-600">Đang tải dữ liệu kết nối hội viên...</span>
</div>
) : (!allData || (allData.responseData.rows || []).length === 0) ? (
<div className="py-12 text-center text-gray-600">Không có dữ liệu</div>
) : (
<>
{allData?.responseData.rows.map((news) => (
{allData.responseData.rows.map((news) => (
<CardNews key={news.id} news={news} />
))}
......@@ -61,7 +63,7 @@ export default function Page() {
{/* Sidebar */}
<aside className="space-y-6">
<ListFilter />
<ListFilter onSearch={setSubmitSearch} />
</aside>
</div>
</div>
......
......@@ -10,14 +10,14 @@ import { GetNewsResponseType } from '@api/types/NewsPage.type'
import { Spinner } from "@components/ui/spinner";
export default function Page() {
const [submitSearch] = useState('')
const [submitSearch,setSubmitSearch] = useState('')
const [page, setPage] = useState(1)
const pageSize = 5
const { data: allData, isLoading } = useGetNews<GetNewsResponseType>({
pageSize: String(pageSize),
currentPage: String(page),
filters: submitSearch ? `title @=${submitSearch}` : 'category @=Tin hội viên',
filters: submitSearch ? `title @=${submitSearch}category@=Tin hội viên` : 'category@=Tin hội viên',
})
return (
<div className="min-h-screen container mx-auto pb-4">
......@@ -27,41 +27,43 @@ export default function Page() {
{/* Main content */}
<main className="lg:col-span-2 bg-background">
<div className='pb-5 overflow-hidden'>
{isLoading ? (
<div className="flex justify-center items-center py-12">
<Spinner className="size-8" />
<span className="ml-2 text-gray-600">Đang tải tin hội viên...</span>
</div>
) : (
<>
{allData?.responseData.rows.map((news) => (
<CardNews key={news.id} news={news} />
))}
{isLoading ? (
<div className="flex justify-center items-center py-12">
<Spinner className="size-8" />
<span className="ml-2 text-gray-600">Đang tải tin hội viên...</span>
</div>
) : (!allData || (allData.responseData.rows || []).length === 0) ? (
<div className="py-12 text-center text-gray-600">Không có dữ liệu</div>
) : (
<>
{allData.responseData.rows.map((news) => (
<CardNews key={news.id} news={news} />
))}
<div className='w-full flex justify-center mt-4'>
<Pagination
pageCount={Number(allData?.responseData.totalPages ?? 1)}
page={Number(allData?.responseData.currentPage ?? page)}
onChangePage={(p) => setPage(p)}
onGoToPreviousPage={() => setPage(Math.max(1, page - 1))}
onGoToNextPage={() =>
setPage(
Math.min(
Number(allData?.responseData.totalPages ?? 1),
page + 1
)
)
}
/>
</div>
</>
)}
<div className='w-full flex justify-center mt-4'>
<Pagination
pageCount={Number(allData?.responseData.totalPages ?? 1)}
page={Number(allData?.responseData.currentPage ?? page)}
onChangePage={(p) => setPage(p)}
onGoToPreviousPage={() => setPage(Math.max(1, page - 1))}
onGoToNextPage={() =>
setPage(
Math.min(
Number(allData?.responseData.totalPages ?? 1),
page + 1
)
)
}
/>
</div>
</>
)}
</div>
</main>
{/* Sidebar */}
<aside className="space-y-6">
<ListFilter />
<ListFilter onSearch={setSubmitSearch} />
</aside>
</div>
</div>
......
......@@ -8,6 +8,7 @@ import { useGetNewsId } from '@/api/endpoints/news';
import parse from "html-react-parser";
import { useParams } from 'next/navigation'
import { GetNewsDetailResponseType } from '@lib/types/news-detail-response-data';
import EventCalendar from '@/components/base/event-calendar'
// ...existing code...
const Page: React.FC = () => {
const { id } = useParams()
......@@ -29,7 +30,7 @@ const Page: React.FC = () => {
{/* Sidebar */}
<aside className="space-y-6">
<ListFilter />
<EventCalendar />
<div className="bg-white border rounded-md overflow-hidden">
<div className="w-full h-56 relative bg-gray-100">
......
......@@ -12,13 +12,13 @@ import { GetNewsResponseType } from "@api/types/NewsPage.type";
import { PATHS } from "@constants/paths";
import { Spinner } from "@components/ui/spinner";
export default function Page() {
const [submitSearch] = useState("");
const [submitSearch,setSubmitSearch] = useState("");
const [page, setPage] = useState(1);
const pageSize = 5;
const { data: allData, isLoading } = useGetNews<GetNewsResponseType>({
pageSize: String(pageSize),
currentPage: String(page),
filters: submitSearch ? `title @=${submitSearch},category @=Chuyên đề` : 'category @=Chuyên đề',
filters: submitSearch ? `title @=${submitSearch},category@=Chuyên đề` : 'category@=Chuyên đề',
});
return (
<div className="min-h-screen container mx-auto p-4">
......@@ -62,7 +62,7 @@ export default function Page() {
{/* Sidebar */}
<aside className="space-y-6">
<ListFilter />
<ListFilter onSearch={setSubmitSearch} />
<div className="bg-white border rounded-md overflow-hidden">
<div className="w-full h-56 relative bg-gray-100">
......
......@@ -8,6 +8,7 @@ import { useGetNewsId } from '@/api/endpoints/news';
import parse from "html-react-parser";
import { useParams } from 'next/navigation'
import { GetNewsDetailResponseType } from '@lib/types/news-detail-response-data';
import EventCalendar from '@/components/base/event-calendar'
// ...existing code...
const Page: React.FC = () => {
const { id } = useParams()
......@@ -29,7 +30,7 @@ const Page: React.FC = () => {
{/* Sidebar */}
<aside className="space-y-6">
<ListFilter />
<EventCalendar />
<div className="bg-white border rounded-md overflow-hidden">
<div className="w-full h-56 relative bg-gray-100">
......
......@@ -10,15 +10,16 @@ import Image from "next/image";
import { useGetNews } from "@api/endpoints/news";
import { GetNewsResponseType } from "@api/types/NewsPage.type";
import { PATHS } from "@constants/paths";
import { Spinner } from "@components/ui/spinner";
export default function Page() {
const [submitSearch] = useState("");
const [submitSearch,setSubmitSearch] = useState("");
const [page, setPage] = useState(1);
const pageSize = 5;
const { data: allData,isLoading } = useGetNews<GetNewsResponseType>({
pageSize: String(pageSize),
currentPage: String(page),
filters: submitSearch ? `title @=${submitSearch},category @=Thông tin chính sách và pháp luật` : 'category @=Thông tin chính sách và pháp luật',
filters: submitSearch ? `title @=${submitSearch},category@=Thông tin chính sách và pháp luật` : 'category @=Thông tin chính sách và pháp luật',
});
return (
<div className="min-h-screen container mx-auto p-4">
......@@ -29,32 +30,40 @@ export default function Page() {
{/* Main content */}
<main className="lg:col-span-2 bg-background ">
<div className="pb-5 overflow-hidden">
{allData?.responseData.rows.length === 0 ? (
{isLoading ? (
<div className="flex justify-center items-center py-12">
<Spinner className="size-8" />
<span className="ml-2 text-gray-600">Đang tải dữ liệu...</span>
</div>
) : (!allData || (allData.responseData.rows || []).length === 0) ? (
<p className="text-center py-4">Không có dữ liệu</p>
) : (
allData?.responseData.rows.map((news) => (
<NewsContent
key={news.id}
news={news}
link={`${PATHS.mediaInformation}/thong-tin-chinh-sach-va-phap-luat/${news.id}`}
/>
)))}
<>
{allData.responseData.rows.map((news) => (
<NewsContent
key={news.id}
news={news}
link={`${PATHS.mediaInformation}/thong-tin-chinh-sach-va-phap-luat/${news.id}`}
/>
))}
<div className="w-full flex justify-center mt-4">
<Pagination
pageCount={Number(allData?.responseData.totalPages ?? 1)}
page={Number(allData?.responseData.currentPage ?? page)}
onChangePage={(p) => setPage(p)}
onGoToPreviousPage={() => setPage(Math.max(1, page - 1))}
onGoToNextPage={() => setPage(Math.min(Number(allData?.responseData.totalPages ?? 1), page + 1))}
/>
</div>
<div className="w-full flex justify-center mt-4">
<Pagination
pageCount={Number(allData?.responseData.totalPages ?? 1)}
page={Number(allData?.responseData.currentPage ?? page)}
onChangePage={(p) => setPage(p)}
onGoToPreviousPage={() => setPage(Math.max(1, page - 1))}
onGoToNextPage={() => setPage(Math.min(Number(allData?.responseData.totalPages ?? 1), page + 1))}
/>
</div>
</>
)}
</div>
</main>
{/* Sidebar */}
<aside className="space-y-6">
<ListFilter />
<ListFilter onSearch={setSubmitSearch} />
<div className="bg-white border rounded-md overflow-hidden">
<div className="w-full h-56 relative bg-gray-100">
......
......@@ -8,6 +8,7 @@ import { useGetNewsId } from '@/api/endpoints/news';
import parse from "html-react-parser";
import { useParams } from 'next/navigation'
import { GetNewsDetailResponseType } from '@lib/types/news-detail-response-data';
import EventCalendar from '@/components/base/event-calendar'
// ...existing code...
const Page: React.FC = () => {
const { id } = useParams()
......@@ -29,7 +30,7 @@ const Page: React.FC = () => {
{/* Sidebar */}
<aside className="space-y-6">
<ListFilter />
<EventCalendar />
<div className="bg-white border rounded-md overflow-hidden">
<div className="w-full h-56 relative bg-gray-100">
......
......@@ -12,7 +12,7 @@ import { GetNewsResponseType } from "@api/types/NewsPage.type";
import { PATHS } from "@constants/paths";
import { Spinner } from "@components/ui/spinner";
export default function Page() {
const [submitSearch] = useState("");
const [submitSearch,setSubmitSearch] = useState("");
const [page, setPage] = useState(1);
const pageSize = 5;
......@@ -63,7 +63,7 @@ export default function Page() {
{/* Sidebar */}
<aside className="space-y-6">
<ListFilter />
<ListFilter onSearch={setSubmitSearch} />
<div className="bg-white border rounded-md overflow-hidden">
<div className="w-full h-56 relative bg-gray-100">
......
......@@ -8,6 +8,7 @@ import { useGetNewsId } from '@/api/endpoints/news';
import parse from "html-react-parser";
import { useParams } from 'next/navigation'
import { GetNewsDetailResponseType } from '@lib/types/news-detail-response-data';
import EventCalendar from '@/components/base/event-calendar'
// ...existing code...
const Page: React.FC = () => {
const { id } = useParams()
......@@ -29,7 +30,7 @@ const Page: React.FC = () => {
{/* Sidebar */}
<aside className="space-y-6">
<ListFilter />
<EventCalendar />
<div className="bg-white border rounded-md overflow-hidden">
<div className="w-full h-56 relative bg-gray-100">
......
......@@ -12,14 +12,14 @@ import { GetNewsResponseType } from "@api/types/NewsPage.type";
import { PATHS } from "@constants/paths";
import { Spinner } from "@components/ui/spinner";
export default function Page() {
const [submitSearch] = useState("");
const [submitSearch,setSubmitSearch] = useState("");
const [page, setPage] = useState(1);
const pageSize = 5;
const { data: allData, isLoading } = useGetNews<GetNewsResponseType>({
pageSize: String(pageSize),
currentPage: String(page),
filters: submitSearch ? `title @=${submitSearch},category @=Tin doanh nghiệp` : 'category @=Tin doanh nghiệp',
filters: submitSearch ? `title @=${submitSearch},category@=Tin doanh nghiệp` : 'category@=Tin doanh nghiệp',
});
return (
<div className="min-h-screen container mx-auto p-4">
......@@ -63,7 +63,7 @@ export default function Page() {
{/* Sidebar */}
<aside className="space-y-6">
<ListFilter />
<ListFilter onSearch={setSubmitSearch} />
<div className="bg-white border rounded-md overflow-hidden">
<div className="w-full h-56 relative bg-gray-100">
......
......@@ -8,6 +8,7 @@ import { useGetNewsId } from '@/api/endpoints/news';
import parse from "html-react-parser";
import { useParams } from 'next/navigation'
import { GetNewsDetailResponseType } from '@lib/types/news-detail-response-data';
import EventCalendar from '@/components/base/event-calendar'
// ...existing code...
const Page: React.FC = () => {
const { id } = useParams()
......@@ -29,7 +30,7 @@ const Page: React.FC = () => {
{/* Sidebar */}
<aside className="space-y-6">
<ListFilter />
<EventCalendar />
<div className="bg-white border rounded-md overflow-hidden">
<div className="w-full h-56 relative bg-gray-100">
......
"use client";
import React, { useState } from "react";
import ListCategory from "@app/dai-dien-gioi-chu/components/list-category";
import {ListFilter} from "@app/dai-dien-gioi-chu/components/list-filter";
import { MEDIA_INFORMATION_CATEGORIES } from "@constants/categories";
// ...existing code...
import NewsContent from "@app/dai-dien-gioi-chu/components/card-news";
import { Pagination } from "@components/base/pagination";
import Image from "next/image";
......@@ -11,14 +11,14 @@ import { GetNewsResponseType } from "@api/types/NewsPage.type";
import { PATHS } from "@constants/paths";
import { Spinner } from "@components/ui/spinner";
export default function Page() {
const [submitSearch] = useState("");
const [submitSearch,setSubmitSearch] = useState("");
const [page, setPage] = useState(1);
const pageSize = 5;
const { data: allData, isLoading } = useGetNews<GetNewsResponseType>({
pageSize: String(pageSize),
currentPage: String(page),
filters: submitSearch ? `title @=${submitSearch},category @=Tin kinh tế` : 'category @=Tin kinh tế',
filters: submitSearch ? `title @=${submitSearch},category@=Tin kinh tế` : 'category@=Tin kinh tế',
});
return (
<div className="min-h-screen container mx-auto p-4">
......@@ -63,7 +63,7 @@ export default function Page() {
{/* Sidebar */}
<aside className="space-y-6">
{/* <EventFilter /> */}
<ListFilter onSearch={setSubmitSearch} />
<div className="bg-white border rounded-md overflow-hidden">
<div className="w-full h-56 relative bg-gray-100">
<Image
......
......@@ -8,6 +8,7 @@ import { useGetNewsId } from '@/api/endpoints/news';
import parse from "html-react-parser";
import { useParams } from 'next/navigation'
import { GetNewsDetailResponseType } from '@lib/types/news-detail-response-data';
import EventCalendar from '@/components/base/event-calendar'
// ...existing code...
const Page: React.FC = () => {
const { id } = useParams()
......@@ -29,7 +30,7 @@ const Page: React.FC = () => {
{/* Sidebar */}
<aside className="space-y-6">
<ListFilter />
<EventCalendar />
<div className="bg-white border rounded-md overflow-hidden">
<div className="w-full h-56 relative bg-gray-100">
......
......@@ -20,7 +20,7 @@ export default function Page() {
const { data: allData, isLoading } = useGetNews<GetNewsResponseType>({
pageSize: String(pageSize),
currentPage: String(page),
filters: submitSearch ? `title @=${submitSearch}` : `category @=Tin VCCI`,
filters: submitSearch ? `title@=${submitSearch}` :undefined,
});
return (
<div className="min-h-screen container mx-auto p-4">
......
......@@ -8,6 +8,7 @@ import { useGetNewsId } from '@/api/endpoints/news';
import parse from "html-react-parser";
import { useParams } from 'next/navigation'
import { GetNewsDetailResponseType } from '@lib/types/news-detail-response-data';
import EventCalendar from '@/components/base/event-calendar'
import { Spinner } from "@components/ui/spinner";
// ...existing code...
const Page: React.FC = () => {
......@@ -39,7 +40,7 @@ const Page: React.FC = () => {
{/* Sidebar */}
<aside className="space-y-6">
<ListFilter />
<EventCalendar />
<div className="bg-white border rounded-md overflow-hidden">
<div className="w-full h-56 relative bg-gray-100">
......
......@@ -9,6 +9,7 @@ import parse from "html-react-parser";
import { useParams } from 'next/navigation'
import { GetNewsDetailResponseType } from '@lib/types/news-detail-response-data';
import { Spinner } from "@components/ui/spinner";
import EventCalendar from '@/components/base/event-calendar'
// ...existing code...
const Page: React.FC = () => {
const { id } = useParams()
......@@ -41,7 +42,7 @@ const Page: React.FC = () => {
{/* Sidebar */}
<aside className="space-y-6">
<ListFilter />
<EventCalendar />
<div className="bg-white border rounded-md overflow-hidden">
<div className="w-full h-56 relative bg-gray-100">
......
......@@ -9,6 +9,7 @@ import parse from "html-react-parser";
import { useParams } from 'next/navigation'
import { GetNewsDetailResponseType } from '@lib/types/news-detail-response-data';
import { Spinner } from "@components/ui/spinner";
import EventCalendar from '@/components/base/event-calendar'
// ...existing code...
const Page: React.FC = () => {
const { id } = useParams()
......@@ -41,7 +42,7 @@ const Page: React.FC = () => {
{/* Sidebar */}
<aside className="space-y-6">
<ListFilter />
<EventCalendar />
<div className="bg-white border rounded-md overflow-hidden">
<div className="w-full h-56 relative bg-gray-100">
......
......@@ -9,6 +9,7 @@ import parse from "html-react-parser";
import { useParams } from 'next/navigation'
import { GetNewsDetailResponseType } from '@lib/types/news-detail-response-data';
import { Spinner } from "@components/ui/spinner";
import EventCalendar from '@/components/base/event-calendar'
// ...existing code...
const Page: React.FC = () => {
const { id } = useParams()
......@@ -41,7 +42,7 @@ const Page: React.FC = () => {
{/* Sidebar */}
<aside className="space-y-6">
<ListFilter />
<EventCalendar />
<div className="bg-white border rounded-md overflow-hidden">
<div className="w-full h-56 relative bg-gray-100">
......
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