Commit 60672bc5 authored by Phạm Quang Bảo's avatar Phạm Quang Bảo

fix/fallback img and active navigation item

parent 21c709a6
......@@ -15,7 +15,7 @@ function CardEvent({ event }: { event: EventItem }) {
className='w-[100px] md:w-[130px] aspect-3/2 object-cover'
onError={(e) => {
e.currentTarget.onerror = null
e.currentTarget.src = "/VCCI-Chung-300x200-1.png"
e.currentTarget.src = "/img-error.png"
}}
/>
<div className='flex-1'>
......
......@@ -15,7 +15,7 @@ function CardNews({ news }: { news: NewsItem }) {
className="w-[100px] md:w-[130px] aspect-3/2 object-cover"
onError={(e) => {
e.currentTarget.onerror = null
e.currentTarget.src = "/VCCI-Chung-300x200-1.png"
e.currentTarget.src = "/img-error.png"
}}
/>
<div className="flex-1">
......
......@@ -186,7 +186,7 @@ const Page = () => {
className="w-full aspect-3/2 sm:h-56 md:h-64 object-cover"
onError={(e) => {
e.currentTarget.onerror = null
e.currentTarget.src = "/VCCI-Chung-300x200-1.png"
e.currentTarget.src = "/img-error.png"
}}
/>
<div className="absolute bottom-0 left-0 right-0 h-20 md:h-24 bg-linear-to-t from-black/80 to-transparent flex items-center justify-center p-3">
......@@ -242,7 +242,7 @@ const Page = () => {
className="w-full h-full object-cover"
onError={(e) => {
e.currentTarget.onerror = null
e.currentTarget.src = "/VCCI-Chung-300x200-1.png"
e.currentTarget.src = "/img-error.png"
}}
/>
</div>
......@@ -380,7 +380,7 @@ const Page = () => {
className="w-full h-full object-cover"
onError={(e) => {
(e.target as HTMLImageElement).src =
"/VCCI-Chung-300x200-1.png";
"/img-error.png";
}}
/>
</div>
......@@ -459,7 +459,7 @@ const Page = () => {
className="w-full h-full object-cover"
onError={(e) => {
e.currentTarget.onerror = null
e.currentTarget.src = "/VCCI-Chung-300x200-1.png"
e.currentTarget.src = "/img-error.png"
}}
/>
<div className="absolute bg-white opacity-80 bottom-5 left-5 right-5 p-5">
......@@ -504,7 +504,7 @@ const Page = () => {
className="w-full h-full object-cover"
onError={(e) => {
e.currentTarget.onerror = null
e.currentTarget.src = "/VCCI-Chung-300x200-1.png"
e.currentTarget.src = "/img-error.png"
}}
/>
<div className="absolute bg-white opacity-80 bottom-5 left-5 right-5 p-5">
......
......@@ -46,7 +46,7 @@ export default function DynamicPage() {
}
if (slug.length === 2) {
return category?.responseData.is_article ? <ArticlePage /> : <InformationPage />;
return category?.responseData?.is_article ? <ArticlePage /> : <InformationPage />;
}
if (slug.length === 3) {
......
......@@ -45,7 +45,7 @@ export default function EventDetailPage() {
<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'>
{eventsDetail?.responseData?.rows[0].name}
{eventsDetail?.responseData?.rows[0]?.name}
</div>
<hr className="py-2" />
......@@ -55,8 +55,8 @@ export default function EventDetailPage() {
{eventsDetail?.responseData?.rows[0].image ? (
<div className="w-full h-52 relative ">
<EventImage
src={`${BASE_URL.imageEndpoint}${eventsDetail.responseData.rows[0].image}`}
alt={eventsDetail.responseData.rows[0].name || "image"}
src={`${BASE_URL.imageEndpoint}${eventsDetail?.responseData?.rows[0].image}`}
alt={eventsDetail?.responseData?.rows[0]?.name || "image"}
/>
</div>
) : (
......@@ -89,8 +89,8 @@ export default function EventDetailPage() {
<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: {eventsDetail?.responseData?.rows[0].location ??
eventsDetail?.responseData?.rows[0].province ??
Địa điểm: {eventsDetail?.responseData?.rows[0]?.location ??
eventsDetail?.responseData?.rows[0]?.province ??
"-"}
</div>
</div>
......@@ -98,9 +98,9 @@ export default function EventDetailPage() {
<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ự: {eventsDetail?.responseData?.rows[0].table_cost
? `${eventsDetail.responseData.rows[0].table_count
} Bàn : ${eventsDetail.responseData.rows[0].table_cost.toLocaleString()} đ`
Phí tham dự: {eventsDetail?.responseData?.rows[0]?.table_cost
? `${eventsDetail?.responseData?.rows[0]?.table_count
} Bàn : ${eventsDetail?.responseData?.rows[0]?.table_cost.toLocaleString()} đ`
: "Vui lòng xem chi tiết trong bài"}
</div>
</div>
......@@ -110,7 +110,7 @@ export default function EventDetailPage() {
{/* Full description */}
<div className="p-7.5 prose tiptap overflow-hidden">
{parse(eventsDetail?.responseData?.rows[0].description ?? "")}
{parse(eventsDetail?.responseData?.rows[0]?.description ?? "")}
</div>
</main>
......@@ -118,12 +118,12 @@ export default function EventDetailPage() {
<aside className="space-y-6">
<EventCalendar />
<div className="bg-white border rounded-md overflow-hidden">
<div className="w-full h-56 relative bg-gray-100">
<div className="w-full h-75 relative bg-gray-100">
<Image
src="/banner.webp"
alt="Quảng cáo"
fill
className="object-cover"
className="object-contain"
/>
</div>
</div>
......@@ -152,7 +152,7 @@ function EventImage({ src, alt }: EventImageProps) {
className="object-cover"
onError={() => {
// swap to local fallback file when Next/Image fails to load the provided URL
if (imgSrc !== "/VCCI-Chung-300x200-1.png") setImgSrc("/VCCI-Chung-300x200-1.png");
if (imgSrc !== "/img-error.png") setImgSrc("/img-error.png");
}}
/>
);
......
......@@ -50,7 +50,7 @@ export default function EventPage() {
<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">
{events?.responseData.rows.map((item) => (
{events?.responseData?.rows?.map((item) => (
<CardEvents
key={item.id}
event={item}
......@@ -59,12 +59,12 @@ export default function EventPage() {
))}
<div className="w-full flex justify-center mt-4">
<Pagination
pageCount={Number(events?.responseData.totalPages ?? 1)}
page={Number(events?.responseData.currentPage ?? page)}
pageCount={Number(events?.responseData?.totalPages ?? 1)}
page={Number(events?.responseData?.currentPage ?? page)}
onChangePage={setPage}
onGoToPreviousPage={() => setPage(Math.max(1, page - 1))}
onGoToNextPage={() =>
setPage(Math.min(Number(events?.responseData.totalPages ?? 1), page + 1))
setPage(Math.min(Number(events?.responseData?.totalPages ?? 1), page + 1))
}
/>
</div>
......
......@@ -37,7 +37,7 @@ export default function InformationPage() {
<ListCategory categories={category?.responseData?.children} />
<main className=" bg-white border rounded-md py-10 px-30">
<div className='text-primary text-2xl leading-normal font-bold'>
{data?.responseData?.rows[0].title}
{data?.responseData?.rows[0]?.title}
</div>
{/* <div className='flex items-center gap-2 text-sm mb-4'>
<span className='text-base text-blue-700'>
......@@ -47,7 +47,7 @@ export default function InformationPage() {
<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 ?? '')}
{parse(data?.responseData?.rows[0]?.description ?? '')}
</div>
</div>
</main>
......
export interface NewsDetailItem {
id: string
title: string
thumbnail: string
external_link: string
description: string
release_at: string
is_active: boolean
created_at: string
created_by: string | null
updated_at: string
updated_by: string | null
mode: 'NOW' | string
category: string
}
export interface NewsDetailResponseData {
count: number
rows: NewsDetailItem[]
totalPages: number
currentPage: number
}
export interface GetNewsDetailResponseType {
message: string
message_en: string
responseData: NewsDetailItem
status: 'success' | 'error'
timeStamp: string
violations: any | null
}
\ No newline at end of file
import { NewsDetailItem } from './CardNews.type';
import { NewsItem } from '@/api/types/news';
import Links from '@links/index'
import dayjs from 'dayjs';
......@@ -20,7 +20,7 @@ const stripImagesAndHtml = (html?: string) => {
return withoutImgs.replace(/<[^>]*>/g, '')
}
const CardNews = ({ news, link }: { news: NewsDetailItem, link: string }) => {
const CardNews = ({ news, link }: { news: NewsItem, link: string }) => {
return (
<a
href={`${link}`}
......
import { usePathname } from "next/navigation";
import Link from "next/link";
type MenuItemProps = {
......@@ -7,26 +8,35 @@ type MenuItemProps = {
};
const MenuItem = ({ title, link, items }: MenuItemProps) => {
const pathname = usePathname();
const isActive = !!link && (pathname === link || (link !== "/" && pathname.startsWith(link)));
return (
<div className="group relative">
<Link
href={`${link || ""}`}
className="px-3 py-5 text-[16px] font-semibold text-[#124588] hover:text-[#E8C518] transition block"
href={link ?? "#"}
className={`px-3 py-5 text-[16px] font-semibold transition block
${isActive ? "text-[#E8C518]" : "text-[#124588] hover:text-[#E8C518]"}
`}
>
{title}
</Link>
{/* Dropdown */}
<div className="absolute left-0 top-full hidden group-hover:block bg-[#124588]/98 text-white text-[14px] font-medium min-w-[220px] shadow-lg">
{items.map((item, i) => (
{items.map((item, i) => {
const isItemActive = pathname === item.link;
return (
<Link
key={i}
href={`${item.link}`}
className="block px-5 py-3 hover:bg-[#e8c518]/80 cursor-pointer whitespace-nowrap transition"
href={item.link}
className={`block px-5 py-3 cursor-pointer whitespace-nowrap transition ${isItemActive ? "bg-[#e8c518]/80" : "hover:bg-[#e8c518]/80"
}`}
>
{item.title}
</Link>
))}
);
})}
</div>
</div>
);
......
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