update 27/01
This commit is contained in:
@@ -1,52 +1,55 @@
|
||||
import { articleList } from "@/data/articles";
|
||||
import ArticleItem from "@/components/shared/ArticleItem";
|
||||
import Link from "next/link";
|
||||
|
||||
export default function Article() {
|
||||
// id: 5 - Tin tức Công nghệ
|
||||
const techNews = articleList
|
||||
.find(article => article.id === 5)
|
||||
?.list.slice(0, 5) || [];
|
||||
|
||||
// id: 19 - Chuyên trang Khuyến mãi
|
||||
const promoNews = articleList
|
||||
.find(article => article.id === 19)
|
||||
?.list.slice(0, 5) || [];
|
||||
|
||||
return(
|
||||
( techNews.length > 0 || promoNews.length > 0) && (
|
||||
<div className="home-article-container bg-white rounded-[24px] p-6 my-8">
|
||||
<div className="mb-8 promotion-news-group">
|
||||
<div className="flex items-center justify-between flex-wrap mb-4 leading-9 gap-4 text-16 font-600">
|
||||
<h2 className="text-[28px] m-0 text-[#004BA4] leading-9"> Chuyên trang Khuyến mãi </h2>
|
||||
<a href="/tin-khuyen-mai" className="text-[#0678DB]"> Xem tất cả <i className="bx bx-chevron-right align-middle ml-[-2px] mt-[-1px] text-18"></i> </a>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-4 gap-6">
|
||||
|
||||
<div className="art-item">
|
||||
<a href="" className="art-img">
|
||||
<img src="https://hoanghapccdn.com/media/news/14_100__c___u_h__nh_m__y_t__nh_______h___a_theo_ng__n_s__ch.jpg" alt="" width="1" height="1" />
|
||||
</a>
|
||||
|
||||
<div className="art-text">
|
||||
<a href="" className="art-title">
|
||||
<h3> Lorem, ipsum dolor sit amet consectetur adipisicing elit. Eum quidem asperiores provident dicta veniam deleniti eaque repudiandae cum esse, ducimus officiis quibusdam pariatur neque voluptates voluptas. Quisquam qui minus dolorum? </h3>
|
||||
</a>
|
||||
|
||||
<div className="art-summary">
|
||||
Lorem ipsum dolor sit, amet consectetur adipisicing elit. Velit, obcaecati ducimus veritatis aliquid sunt accusamus unde nisi nostrum fugit facere illo quos. Ad error suscipit, quidem optio aut laudantium at!
|
||||
</div>
|
||||
|
||||
<div className="art-time">
|
||||
<i className='bx bx-calendar-alt text-16 text-[#A0A5AC]'></i>
|
||||
<time> 23/4/2024 </time>
|
||||
<i className="w-[1.5px] h-[12px] bg-[#A0A5AC]"></i>
|
||||
<span> Mai Văn Học </span>
|
||||
</div>
|
||||
</div>
|
||||
{techNews &&
|
||||
<div className="mb-8 promotion-news-group">
|
||||
<div className="flex items-center justify-between flex-wrap mb-4 leading-9 gap-4 text-16 font-600">
|
||||
<h2 className="text-[28px] m-0 text-[#004BA4] leading-9"> Chuyên trang Khuyến mãi </h2>
|
||||
<Link href="/tin-khuyen-mai" className="text-[#0678DB]"> Xem tất cả <i className="bx bx-chevron-right align-middle ml-[-2px] mt-[-1px] text-18"></i> </Link>
|
||||
</div>
|
||||
|
||||
<div className="art-item"><a href="" className="art-img"><img src="https://hoanghapccdn.com/media/news/14_100__c___u_h__nh_m__y_t__nh_______h___a_theo_ng__n_s__ch.jpg" alt="" width="1" height="1"/></a><div className="art-text"><a href="" className="art-title"><h3>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Eum quidem asperiores provident dicta veniam deleniti eaque repudiandae cum esse, ducimus officiis quibusdam pariatur neque voluptates voluptas. Quisquam qui minus dolorum?</h3></a><div className="art-summary">Lorem ipsum dolor sit, amet consectetur adipisicing elit. Velit, obcaecati ducimus veritatis aliquid sunt accusamus unde nisi nostrum fugit facere illo quos. Ad error suscipit, quidem optio aut laudantium at!</div><div className="art-time"><i className="bx bx-calendar-alt"></i><time>23/4/2024</time><i className="w-[1.5px] h-[12px] bg-[#A0A5AC] mx-1"></i><span>Mai Văn Học</span></div></div></div><div className="art-item"><a href="" className="art-img"><img src="https://hoanghapccdn.com/media/news/14_100__c___u_h__nh_m__y_t__nh_______h___a_theo_ng__n_s__ch.jpg" alt="" width="1" height="1"/></a><div className="art-text"><a href="" className="art-title"><h3>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Eum quidem asperiores provident dicta veniam deleniti eaque repudiandae cum esse, ducimus officiis quibusdam pariatur neque voluptates voluptas. Quisquam qui minus dolorum?</h3></a><div className="art-summary">Lorem ipsum dolor sit, amet consectetur adipisicing elit. Velit, obcaecati ducimus veritatis aliquid sunt accusamus unde nisi nostrum fugit facere illo quos. Ad error suscipit, quidem optio aut laudantium at!</div><div className="art-time"><i className="bx bx-calendar-alt text-16 text-[#A0A5AC]"></i><time>23/4/2024</time><i className="w-[1.5px] h-[12px] bg-[#A0A5AC]"></i><span>Mai Văn Học</span></div></div></div><div className="art-item"><a href="" className="art-img"><img src="https://hoanghapccdn.com/media/news/14_100__c___u_h__nh_m__y_t__nh_______h___a_theo_ng__n_s__ch.jpg" alt="" width="1" height="1"/></a><div className="art-text"><a href="" className="art-title"><h3>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Eum quidem asperiores provident dicta veniam deleniti eaque repudiandae cum esse, ducimus officiis quibusdam pariatur neque voluptates voluptas. Quisquam qui minus dolorum?</h3></a><div className="art-summary">Lorem ipsum dolor sit, amet consectetur adipisicing elit. Velit, obcaecati ducimus veritatis aliquid sunt accusamus unde nisi nostrum fugit facere illo quos. Ad error suscipit, quidem optio aut laudantium at!</div><div className="art-time"><i className="bx bx-calendar-alt text-16 text-[#A0A5AC]"></i><time>23/4/2024</time><i className="w-[1.5px] h-[12px] bg-[#A0A5AC]"></i><span>Mai Văn Học</span></div></div></div><div className="art-item"><a href="" className="art-img"><img src="https://hoanghapccdn.com/media/news/14_100__c___u_h__nh_m__y_t__nh_______h___a_theo_ng__n_s__ch.jpg" alt="" width="1" height="1"/></a><div className="art-text"><a href="" className="art-title"><h3>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Eum quidem asperiores provident dicta veniam deleniti eaque repudiandae cum esse, ducimus officiis quibusdam pariatur neque voluptates voluptas. Quisquam qui minus dolorum?</h3></a><div className="art-summary">Lorem ipsum dolor sit, amet consectetur adipisicing elit. Velit, obcaecati ducimus veritatis aliquid sunt accusamus unde nisi nostrum fugit facere illo quos. Ad error suscipit, quidem optio aut laudantium at!</div><div className="art-time"><i className="bx bx-calendar-alt text-16 text-[#A0A5AC]"></i><time>23/4/2024</time><i className="w-[1.5px] h-[12px] bg-[#A0A5AC]"></i><span>Mai Văn Học</span></div></div></div>
|
||||
<div className="grid grid-cols-4 gap-6">
|
||||
{
|
||||
techNews.map( (item:any) => (
|
||||
<ArticleItem key={item.id} item={item} />
|
||||
))
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
</div>
|
||||
{promoNews &&
|
||||
<div>
|
||||
<div className="flex items-center justify-between flex-wrap mb-4 leading-9 gap-4 text-16 font-600">
|
||||
<h2 className="text-[28px] m-0 text-[#004BA4] leading-9"> Tin tức Công nghệ </h2>
|
||||
<Link href="/tin-cong-nghe" className="text-[#0678DB]"> Xem tất cả <i className="bx bx-chevron-right align-middle ml-[-2px] mt-[-1px] text-18"></i> </Link>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div className="flex items-center justify-between flex-wrap mb-4 leading-9 gap-4 text-16 font-600">
|
||||
<h2 className="text-[28px] m-0 text-[#004BA4] leading-9"> Tin tức Công nghệ </h2>
|
||||
<a href="/tin-cong-nghe" className="text-[#0678DB]"> Xem tất cả <i className="bx bx-chevron-right align-middle ml-[-2px] mt-[-1px] text-18"></i> </a>
|
||||
<div className="grid grid-cols-4 gap-6">
|
||||
{
|
||||
promoNews.map( (item:any) => (
|
||||
<ArticleItem key={item.id} item={item} />
|
||||
))
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-4 gap-6">
|
||||
<div className="art-item"><a href="" className="art-img"><img src="https://hoanghapccdn.com/media/news/14_100__c___u_h__nh_m__y_t__nh_______h___a_theo_ng__n_s__ch.jpg" alt="" width="1" height="1"/></a><div className="art-text"><a href="" className="art-title"><h3>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Eum quidem asperiores provident dicta veniam deleniti eaque repudiandae cum esse, ducimus officiis quibusdam pariatur neque voluptates voluptas. Quisquam qui minus dolorum?</h3></a><div className="art-summary">Lorem ipsum dolor sit, amet consectetur adipisicing elit. Velit, obcaecati ducimus veritatis aliquid sunt accusamus unde nisi nostrum fugit facere illo quos. Ad error suscipit, quidem optio aut laudantium at!</div><div className="art-time"><i className="bx bx-calendar-alt"></i><time>23/4/2024</time><i className="w-[1.5px] h-[12px] bg-[#A0A5AC] mx-1"></i><span>Mai Văn Học</span></div></div></div><div className="art-item"><a href="" className="art-img"><img src="https://hoanghapccdn.com/media/news/14_100__c___u_h__nh_m__y_t__nh_______h___a_theo_ng__n_s__ch.jpg" alt="" width="1" height="1"/></a><div className="art-text"><a href="" className="art-title"><h3>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Eum quidem asperiores provident dicta veniam deleniti eaque repudiandae cum esse, ducimus officiis quibusdam pariatur neque voluptates voluptas. Quisquam qui minus dolorum?</h3></a><div className="art-summary">Lorem ipsum dolor sit, amet consectetur adipisicing elit. Velit, obcaecati ducimus veritatis aliquid sunt accusamus unde nisi nostrum fugit facere illo quos. Ad error suscipit, quidem optio aut laudantium at!</div><div className="art-time"><i className="bx bx-calendar-alt text-16 text-[#A0A5AC]"></i><time>23/4/2024</time><i className="w-[1.5px] h-[12px] bg-[#A0A5AC]"></i><span>Mai Văn Học</span></div></div></div><div className="art-item"><a href="" className="art-img"><img src="https://hoanghapccdn.com/media/news/14_100__c___u_h__nh_m__y_t__nh_______h___a_theo_ng__n_s__ch.jpg" alt="" width="1" height="1"/></a><div className="art-text"><a href="" className="art-title"><h3>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Eum quidem asperiores provident dicta veniam deleniti eaque repudiandae cum esse, ducimus officiis quibusdam pariatur neque voluptates voluptas. Quisquam qui minus dolorum?</h3></a><div className="art-summary">Lorem ipsum dolor sit, amet consectetur adipisicing elit. Velit, obcaecati ducimus veritatis aliquid sunt accusamus unde nisi nostrum fugit facere illo quos. Ad error suscipit, quidem optio aut laudantium at!</div><div className="art-time"><i className="bx bx-calendar-alt text-16 text-[#A0A5AC]"></i><time>23/4/2024</time><i className="w-[1.5px] h-[12px] bg-[#A0A5AC]"></i><span>Mai Văn Học</span></div></div></div><div className="art-item"><a href="" className="art-img"><img src="https://hoanghapccdn.com/media/news/14_100__c___u_h__nh_m__y_t__nh_______h___a_theo_ng__n_s__ch.jpg" alt="" width="1" height="1"/></a><div className="art-text"><a href="" className="art-title"><h3>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Eum quidem asperiores provident dicta veniam deleniti eaque repudiandae cum esse, ducimus officiis quibusdam pariatur neque voluptates voluptas. Quisquam qui minus dolorum?</h3></a><div className="art-summary">Lorem ipsum dolor sit, amet consectetur adipisicing elit. Velit, obcaecati ducimus veritatis aliquid sunt accusamus unde nisi nostrum fugit facere illo quos. Ad error suscipit, quidem optio aut laudantium at!</div><div className="art-time"><i className="bx bx-calendar-alt text-16 text-[#A0A5AC]"></i><time>23/4/2024</time><i className="w-[1.5px] h-[12px] bg-[#A0A5AC]"></i><span>Mai Văn Học</span></div></div></div><div className="art-item"><a href="" className="art-img"><img src="https://hoanghapccdn.com/media/news/14_100__c___u_h__nh_m__y_t__nh_______h___a_theo_ng__n_s__ch.jpg" alt="" width="1" height="1"/></a><div className="art-text"><a href="" className="art-title"><h3>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Eum quidem asperiores provident dicta veniam deleniti eaque repudiandae cum esse, ducimus officiis quibusdam pariatur neque voluptates voluptas. Quisquam qui minus dolorum?</h3></a><div className="art-summary">Lorem ipsum dolor sit, amet consectetur adipisicing elit. Velit, obcaecati ducimus veritatis aliquid sunt accusamus unde nisi nostrum fugit facere illo quos. Ad error suscipit, quidem optio aut laudantium at!</div><div className="art-time"><i className="bx bx-calendar-alt text-16 text-[#A0A5AC]"></i><time>23/4/2024</time><i className="w-[1.5px] h-[12px] bg-[#A0A5AC]"></i><span>Mai Văn Học</span></div></div></div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
)
|
||||
)
|
||||
}
|
||||
@@ -3,6 +3,7 @@ import { Swiper, SwiperSlide } from 'swiper/react';
|
||||
import { Navigation, Pagination, Autoplay } from 'swiper/modules';
|
||||
import { dealList } from "@/data/deals"
|
||||
import DealItem from "@/components/shared/DealItem"
|
||||
import Link from 'next/link';
|
||||
|
||||
export default function Collection() {
|
||||
|
||||
@@ -24,7 +25,7 @@ export default function Collection() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a href='/deal' className="text-16 font-600"> Xem tất cả <i className="bx bx-chevron-right align-middle ml-[-2px] mt-[-1px]"></i> </a>
|
||||
<Link href='/deal' className="text-16 font-600"> Xem tất cả <i className="bx bx-chevron-right align-middle ml-[-2px] mt-[-1px]"></i> </Link>
|
||||
</div>
|
||||
|
||||
<div className="group relative z-[1] bg-white rounded-[12px] relative min-h-[450px] px-4 pt-6 pb-8">
|
||||
|
||||
@@ -5,6 +5,7 @@ import { categories } from "@/data/categories"
|
||||
import { productList } from '@/data/products';
|
||||
import CategoryIcon from "./CategoryIcon"
|
||||
import ProductItem from "@/components/shared/ProductItem"
|
||||
import Link from 'next/link';
|
||||
|
||||
export default function ProductCategories() {
|
||||
|
||||
@@ -34,12 +35,12 @@ export default function ProductCategories() {
|
||||
item.children
|
||||
.slice(0, 4)
|
||||
.map((child: any) =>
|
||||
<a href={child.url} key={child.id}
|
||||
<Link href={child.url} key={child.id}
|
||||
className="px-2 rounded-[30px] bg-[#EAF1FF]"
|
||||
> {child.title} </a>
|
||||
> {child.title} </Link>
|
||||
)
|
||||
}
|
||||
<a href={item.url}> Xem tất cả <i className="bx bx-chevron-right text-20 align-middle"></i> </a>
|
||||
<Link href={item.url}> Xem tất cả <i className="bx bx-chevron-right text-20 align-middle"></i> </Link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import Link from "next/link";
|
||||
import { categories } from "@/data/categories";
|
||||
|
||||
export default function FeaturedProductCategories() {
|
||||
@@ -32,7 +33,7 @@ export default function FeaturedProductCategories() {
|
||||
<div className="grid grid-cols-10 gap-6">
|
||||
{featuredCategories
|
||||
.map( (item:any) =>
|
||||
<a href={item.url} className="item" key={item.id}>
|
||||
<Link href={item.url} className="item" key={item.id}>
|
||||
<i className="image lazy"
|
||||
style={{ backgroundImage: `url(${item.thumnail ? item.thumnail : '/images/avatar-admin.png'})` }}
|
||||
></i>
|
||||
@@ -40,7 +41,7 @@ export default function FeaturedProductCategories() {
|
||||
<span className="block">
|
||||
{item.title}
|
||||
</span>
|
||||
</a>
|
||||
</Link>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
export default function ProductFilter() {
|
||||
export default function ProductFilter({data}: any) {
|
||||
console.log( data)
|
||||
return (
|
||||
<>
|
||||
<p className="uppercase font-500 text-center border text-[#0678DB] leading-10 border-[#114CDD] rounded-[8px] mb-6">
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
export default function Paging() {
|
||||
return (
|
||||
<div className="text-center mt-12">
|
||||
<button
|
||||
type="button"
|
||||
className="mb-3 bg-btn text-white rounded-[30px] h-10 font-500 text-16 table max-w-[240px] w-full m-auto mb-3"
|
||||
aria-label="Xem thêm"
|
||||
>
|
||||
TẢI THÊM
|
||||
</button>
|
||||
<p className="text-14 leading-[18px] m-0">
|
||||
{" "}
|
||||
Hiển thị 1 - 24 trên tổng số 124 sản phẩm{" "}
|
||||
</p>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -1,22 +1,23 @@
|
||||
import { productCategory } from "@/data/productCategory";
|
||||
|
||||
import ProductFilter from "./filter";
|
||||
import Static from "./static";
|
||||
import FAQ from "./faq";
|
||||
import Banner from "./banner";
|
||||
import SortByCollection from "./sort";
|
||||
import ProductList from "./productList";
|
||||
import Paging from "./paging";
|
||||
|
||||
export default function ProductCategory({ slug }: { slug: string }) {
|
||||
|
||||
export default function ProductCategory({ slug }: any) {
|
||||
const { name,id, static_html } = productCategory.current_category
|
||||
return(
|
||||
<div className="product-page container">
|
||||
<h1 className="text-[#004BA4] text-[32px] leading-10 mb-4 font-600">
|
||||
PC THIẾT KẾ ĐỒ HỌA 3D
|
||||
{name}
|
||||
</h1>
|
||||
|
||||
<div className="product-page-content flex flex-wrap items-start gap-4 mb-5">
|
||||
<div className="col-left-group w-[264px] rounded-[16px] bg-white p-4 pb-6">
|
||||
<ProductFilter />
|
||||
<ProductFilter data={slug} />
|
||||
</div>
|
||||
|
||||
<div className="col-right-group w-[968px]">
|
||||
@@ -25,12 +26,12 @@ export default function ProductCategory({ slug }: { slug: string }) {
|
||||
|
||||
<SortByCollection />
|
||||
|
||||
<ProductList />
|
||||
|
||||
<Paging />
|
||||
<ProductList id={id}/>
|
||||
</div>
|
||||
|
||||
<Static />
|
||||
{static_html &&
|
||||
<Static data={static_html} />
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
54
src/components/shared/ArticleItem.tsx
Normal file
54
src/components/shared/ArticleItem.tsx
Normal file
@@ -0,0 +1,54 @@
|
||||
import Link from "next/link";
|
||||
import { formatArticleTime } from "@/lib/utils";
|
||||
|
||||
export default function ArticleItem({ item }: any) {
|
||||
const url = item.external_url ? item.external_url : item.url;
|
||||
const time = item.article_time ? item.article_time : item.lastUpdate;
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="art-item" data-id={item.id}>
|
||||
<Link href={url} className="art-img"
|
||||
{...(item.external_url ? {
|
||||
target: "_blank",
|
||||
rel: "noopener noreferrer"
|
||||
} : {})}
|
||||
>
|
||||
<img src={item.image.original}
|
||||
alt={item.title}
|
||||
width={100}
|
||||
height={100} />
|
||||
</Link>
|
||||
|
||||
<div className="art-text">
|
||||
<Link href={url} className="art-title"
|
||||
{...(item.external_url ? {
|
||||
target: "_blank",
|
||||
rel: "noopener noreferrer"
|
||||
} : {})}
|
||||
>
|
||||
<h3> {item.title} </h3>
|
||||
</Link>
|
||||
|
||||
<div className="art-summary">
|
||||
{item.summary}
|
||||
</div>
|
||||
|
||||
<div className="art-time">
|
||||
<i className='bx bx-calendar-alt text-16 text-[#A0A5AC]'></i>
|
||||
<time>
|
||||
{ formatArticleTime(time) }
|
||||
</time>
|
||||
|
||||
{ item.create_by_name && (
|
||||
<>
|
||||
<i className="w-[1.5px] h-[12px] bg-[#A0A5AC]"></i>
|
||||
<span> {item.create_by_name} </span>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -3,13 +3,21 @@ import Link from "next/link";
|
||||
import { formatPrice } from "@/lib/utils";
|
||||
import { useProductItem } from "@/hooks/useProductItem"
|
||||
import { useCart } from '@/hooks/useCart';
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
export default function ProductItem({item}:any){
|
||||
const [mounted, setMounted] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
setMounted(true);
|
||||
}, []);
|
||||
|
||||
const product = useProductItem(item);
|
||||
if (!product) return null;
|
||||
|
||||
const { addToCart, isInCart } = useCart();
|
||||
|
||||
if (!mounted || !product) return null;
|
||||
|
||||
const {
|
||||
productId,
|
||||
productUrl,
|
||||
@@ -123,7 +131,8 @@ export default function ProductItem({item}:any){
|
||||
</p>
|
||||
|
||||
<div className="tooltip-spec">
|
||||
<div dangerouslySetInnerHTML={{ __html: displaySummary }}/>
|
||||
<div suppressHydrationWarning
|
||||
dangerouslySetInnerHTML={{ __html: displaySummary }}/>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
@@ -136,7 +145,8 @@ export default function ProductItem({item}:any){
|
||||
</p>
|
||||
|
||||
<div className="tooltip-offer rounded-[8px] bg-[#FEF2F2] px-2 py-4">
|
||||
<div dangerouslySetInnerHTML={{ __html: displayOffer }}/>
|
||||
<div suppressHydrationWarning
|
||||
dangerouslySetInnerHTML={{ __html: displayOffer }}/>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
605
src/data/productCategory/index.tsx
Normal file
605
src/data/productCategory/index.tsx
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -23,16 +23,14 @@ export function useCart() {
|
||||
setCartItems(getCartItems());
|
||||
}, []);
|
||||
|
||||
// Listen to cart changes from ANY source
|
||||
|
||||
useEffect(() => {
|
||||
const handleCartChange = () => {
|
||||
setCartItems(getCartItems());
|
||||
};
|
||||
|
||||
// Listen to custom event
|
||||
window.addEventListener(CART_CHANGE_EVENT, handleCartChange);
|
||||
|
||||
// Also listen to storage event (for changes from other tabs)
|
||||
window.addEventListener('storage', (e) => {
|
||||
if (e.key === 'cart_products') {
|
||||
handleCartChange();
|
||||
@@ -51,18 +49,16 @@ export function useCart() {
|
||||
|
||||
const addToCart = useCallback((productId: number, quantity: number = 1) => {
|
||||
const result = addProductToCart(productId, quantity);
|
||||
// Không cần refresh() nữa vì event listener sẽ tự động update
|
||||
|
||||
return result;
|
||||
}, []);
|
||||
|
||||
const removeFromCart = useCallback((productId: number) => {
|
||||
removeProductFromCart(productId);
|
||||
// Không cần refresh()
|
||||
}, []);
|
||||
|
||||
const increase = useCallback((productId: number, amount: number = 1) => {
|
||||
const success = increaseQuantity(productId, amount);
|
||||
// Không cần refresh()
|
||||
return success;
|
||||
}, []);
|
||||
|
||||
@@ -71,7 +67,7 @@ export function useCart() {
|
||||
if (!success) {
|
||||
console.log('Số lượng tối thiểu: 1');
|
||||
}
|
||||
// Không cần refresh()
|
||||
|
||||
return success;
|
||||
}, []);
|
||||
|
||||
@@ -80,13 +76,13 @@ export function useCart() {
|
||||
if (!success) {
|
||||
console.log('Số lượng phải lớn hơn hoặc bằng 1');
|
||||
}
|
||||
// Không cần refresh()
|
||||
|
||||
return success;
|
||||
}, []);
|
||||
|
||||
const clear = useCallback(() => {
|
||||
clearCart();
|
||||
// Không cần setCartItems([]) nữa, event sẽ tự động update
|
||||
|
||||
}, []);
|
||||
|
||||
const isInCart = useCallback(
|
||||
|
||||
@@ -16,9 +16,9 @@ export function useProductItem(item: ProductItemProps) {
|
||||
const productImage = item.productImage.large;
|
||||
const productName = item.productName;
|
||||
const specialOffer = item.specialOffer.all[0]?.title ?? null;
|
||||
const displayOffer = specialOffer
|
||||
? formatTextList(specialOffer)
|
||||
: null;
|
||||
const displayOffer = specialOffer
|
||||
? formatTextList(specialOffer)
|
||||
: null;
|
||||
|
||||
const warranty = item.warranty;
|
||||
const productSummary = item.productSummary;
|
||||
|
||||
@@ -6,60 +6,53 @@ export function useTooltip() {
|
||||
useEffect(() => {
|
||||
const tooltip = document.getElementById('js-tooltip') as HTMLDivElement | null;
|
||||
if (!tooltip) return;
|
||||
const tooltipElement = tooltip!;
|
||||
|
||||
const pad = 10;
|
||||
|
||||
function onMouseMove(e: MouseEvent) {
|
||||
const img = e.currentTarget as HTMLElement | null;
|
||||
if (!img) return;
|
||||
|
||||
const product = img.closest('.js-p-item');
|
||||
const content = product?.querySelector<HTMLElement>('.p-tooltip');
|
||||
|
||||
if (!content) {
|
||||
tooltip.style.display = 'none';
|
||||
const target = e.target as HTMLElement;
|
||||
const product = target.closest('.js-p-item');
|
||||
if (!product) {
|
||||
tooltipElement.style.display = 'none';
|
||||
return;
|
||||
}
|
||||
|
||||
tooltip.innerHTML = content.innerHTML;
|
||||
tooltip.style.display = 'block';
|
||||
const content = product.querySelector<HTMLElement>('.p-tooltip');
|
||||
if (!content) return;
|
||||
|
||||
const w = tooltip.offsetWidth;
|
||||
const h = tooltip.offsetHeight;
|
||||
tooltipElement.innerHTML = content.innerHTML;
|
||||
tooltipElement.style.display = 'block';
|
||||
|
||||
const wrapRight = window.innerWidth;
|
||||
const wrapTop = window.scrollY;
|
||||
const w = tooltipElement.offsetWidth;
|
||||
const h = tooltipElement.offsetHeight;
|
||||
|
||||
const left =
|
||||
e.pageX + w > wrapRight
|
||||
? e.pageX - w - pad
|
||||
: e.pageX + pad;
|
||||
const left = e.pageX + w > window.innerWidth
|
||||
? e.pageX - w - pad
|
||||
: e.pageX + pad;
|
||||
|
||||
const top =
|
||||
e.pageY - h < wrapTop
|
||||
? wrapTop
|
||||
: e.pageY - h - pad;
|
||||
const top = e.pageY - h < window.scrollY
|
||||
? window.scrollY
|
||||
: e.pageY - h - pad;
|
||||
|
||||
tooltip.style.left = `${left}px`;
|
||||
tooltip.style.top = `${top}px`;
|
||||
tooltipElement.style.left = `${left}px`;
|
||||
tooltipElement.style.top = `${top}px`;
|
||||
}
|
||||
|
||||
function onMouseOut() {
|
||||
tooltip.style.display = 'none';
|
||||
function onMouseOut(e: MouseEvent) {
|
||||
const target = e.target as HTMLElement;
|
||||
if (!target.closest('.js-p-item')) {
|
||||
tooltipElement.style.display = 'none';
|
||||
}
|
||||
}
|
||||
|
||||
const images = document.querySelectorAll<HTMLImageElement>('.js-p-item img');
|
||||
|
||||
images.forEach(img => {
|
||||
img.addEventListener('mousemove', onMouseMove);
|
||||
img.addEventListener('mouseout', onMouseOut);
|
||||
});
|
||||
document.addEventListener('mousemove', onMouseMove);
|
||||
document.addEventListener('mouseout', onMouseOut);
|
||||
|
||||
return () => {
|
||||
images.forEach(img => {
|
||||
img.removeEventListener('mousemove', onMouseMove);
|
||||
img.removeEventListener('mouseout', onMouseOut);
|
||||
});
|
||||
document.removeEventListener('mousemove', onMouseMove);
|
||||
document.removeEventListener('mouseout', onMouseOut);
|
||||
};
|
||||
}, []);
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// src/lib/articlePage.ts
|
||||
import { categories } from "@/data/categories";
|
||||
import { articleList } from "@/data/articles";
|
||||
|
||||
export type ArticleResult =
|
||||
| { type: "article_home"; data: any }
|
||||
@@ -29,8 +30,10 @@ export function resolveArticlePage(slug: string): ArticleResult | null {
|
||||
}
|
||||
|
||||
// DETAIL
|
||||
const isValidSlugFormat = slug.includes('-') && slug.length > 5;
|
||||
if (!isValidSlugFormat) {
|
||||
return null;
|
||||
const allArticles = articleList.flatMap(article => article.list);
|
||||
for (const article of allArticles) {
|
||||
if (article.url === url) {
|
||||
return { type: "article_detail", data: { slug } };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { notFound } from "next/navigation";
|
||||
import { resolveArticlePage } from "./resolveArticlePage";
|
||||
import { resolveProductPage } from "./resolveProductPage";
|
||||
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
import { ReactNode } from 'react';
|
||||
|
||||
|
||||
// Add tất cả sp trong data product vào 1 mảng
|
||||
import { productList } from '@/data/products';
|
||||
|
||||
@@ -56,3 +53,23 @@ export function calculateDiscount(
|
||||
if (price <= 0 || marketPrice <= price) return 0;
|
||||
return Math.ceil(((marketPrice - price) / marketPrice) * 100);
|
||||
}
|
||||
|
||||
export function formatArticleTime(article_time:string) {
|
||||
let day: string;
|
||||
let month: string;
|
||||
let year: string;
|
||||
|
||||
if (article_time.toLowerCase().includes('hôm nay')) {
|
||||
const time = new Date();
|
||||
day = (time.getDate() <= 9) ? '0' + time.getDate() : String(time.getDate());
|
||||
month = (time.getMonth()+1 <= 9) ? '0' + (time.getMonth()+1) : String(time.getMonth()+1);
|
||||
year = String(time.getFullYear());
|
||||
} else {
|
||||
day = article_time.substring(0,2);
|
||||
month = article_time.substring(3,5);
|
||||
year = article_time.substring(6,10);
|
||||
}
|
||||
return `${day}/${month}/${year}`;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -27,7 +27,8 @@
|
||||
{
|
||||
"name": "next"
|
||||
}
|
||||
]
|
||||
],
|
||||
"ignoreDeprecations": "6.0"
|
||||
},
|
||||
"include": [
|
||||
"next-env.d.ts",
|
||||
|
||||
Reference in New Issue
Block a user