Commit e7182338 authored by Văn Hoàng's avatar Văn Hoàng

[tag]0.1-vcci

parents fe00b726 2642b7b8
Pipeline #44188 passed with stages
in 8 minutes and 50 seconds
......@@ -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>
......@@ -312,9 +312,6 @@ const Page = () => {
<h2 className="text-[18px] sm:text-[20px] font-semibold uppercase text-[#063e8e]">
Liên kết nhanh
</h2>
<a href="#" className="text-[#063e8e] text-sm sm:text-base">
<ChevronsRight />
</a>
</div>
<hr className="border-[#063e8e] mb-4" />
<div className="space-y-2 text-[#063e8e] text-sm md:text-base pb-10">
......@@ -380,7 +377,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 +456,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 +501,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">
......@@ -539,7 +536,7 @@ const Page = () => {
Hội viên tiêu biểu
</h2>
<a
href="#"
href="/danh-ba-hoi-vien"
className="text-[#063e8e] hover:underline text-sm font-medium"
>
<ChevronsRight />
......@@ -576,17 +573,11 @@ const Page = () => {
</aside >
{/* right */}
< aside className="w-full lg:w-[30%] py-5" >
<aside className="w-full lg:w-[30%] py-5" >
<div className="flex justify-between items-center mb-3">
<h2 className="text-xl font-bold uppercase text-[#063e8e]">
Kết nối hội viên
</h2>
<a
href="#"
className="text-[#063e8e] hover:underline text-sm font-medium"
>
<ChevronsRight />
</a>
</div>
<hr className="border-[#063e8e] mb-5" />
<div className="pb-10">
......@@ -628,7 +619,7 @@ const Page = () => {
Video
</h2>
<a
href="#"
href="/video"
className="text-[#063e8e] hover:underline text-sm font-medium"
>
<ChevronsRight />
......@@ -672,12 +663,6 @@ const Page = () => {
<h2 className="text-xl font-bold uppercase text-[#063e8e]">
Đối tác
</h2>
<a
href="#"
className="text-[#063e8e] hover:underline text-sm font-medium"
>
<ChevronsRight />
</a>
</div>
<hr className="border-[#063e8e] mb-5" />
<div className="pb-10">
......
......@@ -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>
......
......@@ -57,15 +57,34 @@ function Header() {
}}
/>
<div className="flex gap-2">
{[Facebook, Twitter, Youtube, Linkedin].map((Icon, i) => (
<a
key={i}
href="#"
className="bg-white size-7 rounded-full flex items-center justify-center text-[#063e8e] hover:opacity-80 transition"
>
<Icon size={16} />
</a>
))}
<a
href="https://www.facebook.com/VCCIHCMC/"
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"
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"
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"
target="_blank"
className="bg-white size-7 rounded-full flex items-center justify-center text-[#063e8e] hover:opacity-80 transition"
>
<Linkedin size={16} />
</a>
</div>
</div>
</div>
......
export default function Page() {
return (
<div className="container flex justify-center items-center h-full py-20">
Danh bạ hội viên đang được xây dựng
</div>
);
}
\ No newline at end of file
"use client";
import React, { useState, Suspense } from "react";
import ListCategory from "@/components/base/list-category";
import ListFilter from "@/components/base/list-filter";
......@@ -13,7 +14,7 @@ import { useSearchParams } from 'next/navigation'
function SearchContent() {
const [page, setPage] = useState(1);
const searchParams = useSearchParams()
const query = searchParams.get('q') //
const query = searchParams.get('q') || '';
const pageSize = 5;
const { data: allData, isLoading } = useGetNews<GetNewsResponseType>({
pageSize: String(pageSize),
......@@ -50,7 +51,7 @@ function SearchContent() {
<CardNews
key={news.id}
news={news}
link={`${news.page_config.static_link}/${news.id}`}
link={news.external_link}
/>
))}
......
export default function Page() {
return (
<div className="container flex justify-center items-center h-full py-20">
Trang video đang được xây dựng
</div>
);
}
\ No newline at end of file
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) => (
<Link
key={i}
href={`${item.link}`}
className="block px-5 py-3 hover:bg-[#e8c518]/80 cursor-pointer whitespace-nowrap transition"
>
{item.title}
</Link>
))}
{items.map((item, i) => {
const isItemActive = pathname === item.link;
return (
<Link
key={i}
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