Compare commits
3 Commits
a499e06b31
...
cb4a4dc482
| Author | SHA1 | Date | |
|---|---|---|---|
| cb4a4dc482 | |||
| 3c18f922b3 | |||
| 52748cb988 |
79
src/app/[slug]/metadataBySlug.tsx
Normal file
79
src/app/[slug]/metadataBySlug.tsx
Normal file
@@ -0,0 +1,79 @@
|
||||
import type { Metadata } from "next";
|
||||
|
||||
export function metadataBySlug(result: any): Metadata {
|
||||
|
||||
switch (result.type) {
|
||||
case "product_category":
|
||||
return {
|
||||
title: result.data.title,
|
||||
description: stripHtml(result.data.summary),
|
||||
openGraph: {
|
||||
type: 'website',
|
||||
images: [
|
||||
result.data.big_image
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
case "product_detail":
|
||||
return {
|
||||
title: result.data.productName,
|
||||
description: stripHtml(result.data.productSummary),
|
||||
openGraph: {
|
||||
type: 'website',
|
||||
images: [
|
||||
result.data.productImage.large.replace('/250_', '/')
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
case "article_home":
|
||||
return {
|
||||
title: "Tin tức",
|
||||
description: "Tin tức mới nhất",
|
||||
openGraph: {
|
||||
type: 'article',
|
||||
images: [
|
||||
result.data.productImage.large.replace('/250_', '/')
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
case "article_category":
|
||||
return {
|
||||
title: result.data.title,
|
||||
description: stripHtml(result.data.summary),
|
||||
openGraph: {
|
||||
type: 'article',
|
||||
images: [
|
||||
result.data.thumbnail
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
case "article_detail":
|
||||
return {
|
||||
title: result.data.title,
|
||||
description: result.data.excerpt,
|
||||
openGraph: {
|
||||
type: 'article',
|
||||
}
|
||||
};
|
||||
|
||||
default:
|
||||
return {
|
||||
title: "Local PC",
|
||||
openGraph: {
|
||||
type: 'website',
|
||||
images: [
|
||||
'/images/logo.png'
|
||||
],
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function stripHtml(html: string) {
|
||||
return html.replace(/<[^>]*>/g, '');
|
||||
}
|
||||
@@ -1,12 +1,33 @@
|
||||
// src/app/[slug]/page.tsx
|
||||
import { notFound } from "next/navigation";
|
||||
// app/[slug]/page.tsx
|
||||
import { cache } from "react";
|
||||
import { renderBySlug } from "./renderBySlug";
|
||||
import { metadataBySlug } from "./metadataBySlug";
|
||||
import { findBySlug } from "@/lib/slug/slugMap";
|
||||
import { notFound } from "next/navigation";
|
||||
import type { Metadata } from "next";
|
||||
|
||||
import ProductCategory from "@/components/product/category";
|
||||
import ProductDetail from "@/components/product/detail";
|
||||
import ArticleCategory from "@/components/article/category";
|
||||
import ArticleDetail from "@/components/article/detail";
|
||||
import ArticleHome from "@/components/article/home";
|
||||
// Cache findBySlug để tránh gọi 2 lần
|
||||
const getCachedSlugData = cache(async (slug: string) => {
|
||||
if (!slug) return null;
|
||||
// fetch data
|
||||
|
||||
return findBySlug(slug);
|
||||
});
|
||||
|
||||
export async function generateMetadata({
|
||||
params,
|
||||
}: {
|
||||
params: Promise<{ slug: string }>;
|
||||
}): Promise<Metadata> {
|
||||
const { slug } = await params;
|
||||
const result = await getCachedSlugData(slug);
|
||||
|
||||
if (!result) {
|
||||
return { title: "Local PC" };
|
||||
}
|
||||
|
||||
return metadataBySlug(result);
|
||||
}
|
||||
|
||||
export default async function SlugPage({
|
||||
params,
|
||||
@@ -14,34 +35,11 @@ export default async function SlugPage({
|
||||
params: Promise<{ slug: string }>;
|
||||
}) {
|
||||
const { slug } = await params;
|
||||
if (!slug) {
|
||||
notFound();
|
||||
}
|
||||
|
||||
const result = findBySlug(slug);
|
||||
const result = await getCachedSlugData(slug);
|
||||
|
||||
if (!result) {
|
||||
notFound();
|
||||
}
|
||||
|
||||
switch (result.type) {
|
||||
case "product_category":
|
||||
return <ProductCategory slug={result.data} />;
|
||||
|
||||
case "product_detail":
|
||||
return <ProductDetail slug={result.data} />;
|
||||
|
||||
case "article_home":
|
||||
return <ArticleHome slug={slug} />;
|
||||
|
||||
case "article_category":
|
||||
return <ArticleCategory slug={result.data} />;
|
||||
|
||||
case "article_detail":
|
||||
return <ArticleDetail slug={result.data.slug} />;
|
||||
|
||||
default:
|
||||
const _exhaustive: never = result;
|
||||
notFound();
|
||||
}
|
||||
return renderBySlug(result, slug);
|
||||
}
|
||||
29
src/app/[slug]/renderBySlug.tsx
Normal file
29
src/app/[slug]/renderBySlug.tsx
Normal file
@@ -0,0 +1,29 @@
|
||||
import { notFound } from "next/navigation";
|
||||
|
||||
import ProductCategory from "@/components/product/category";
|
||||
import ProductDetail from "@/components/product/detail";
|
||||
import ArticleCategory from "@/components/article/category";
|
||||
import ArticleDetail from "@/components/article/detail";
|
||||
import ArticleHome from "@/components/article/home";
|
||||
|
||||
export function renderBySlug(result: any, slug: string) {
|
||||
switch (result.type) {
|
||||
case "product_category":
|
||||
return <ProductCategory slug={result.data} />;
|
||||
|
||||
case "product_detail":
|
||||
return <ProductDetail slug={result.data} />;
|
||||
|
||||
case "article_home":
|
||||
return <ArticleHome slug={slug} />;
|
||||
|
||||
case "article_category":
|
||||
return <ArticleCategory slug={result.data} />;
|
||||
|
||||
case "article_detail":
|
||||
return <ArticleDetail slug={result.data} />;
|
||||
|
||||
default:
|
||||
notFound();
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,7 @@ import TooltipProvider from "@/components/providers/TooltipProvider";
|
||||
import '../styles/globals.css';
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Local Pc",
|
||||
title: "Homepage- Local Pc",
|
||||
description: "hoanghapc",
|
||||
};
|
||||
|
||||
|
||||
@@ -3,8 +3,6 @@ import Home from "@/components/home";
|
||||
|
||||
export default function HomePage() {
|
||||
return (
|
||||
<>
|
||||
<Home />
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
|
||||
import ArticleHome from "@/components/article/home";
|
||||
import type { Metadata } from "next";
|
||||
export const metadata: Metadata = {
|
||||
title: "Tin tức ",
|
||||
description: "hoanghapc",
|
||||
};
|
||||
|
||||
export default function Home() {
|
||||
return (
|
||||
<ArticleHome slug="" />
|
||||
<ArticleHome />
|
||||
)
|
||||
}
|
||||
|
||||
47
src/components/article/Category/article/index.tsx
Normal file
47
src/components/article/Category/article/index.tsx
Normal file
@@ -0,0 +1,47 @@
|
||||
import Link from "next/link";
|
||||
import { categories } from "@/data/categories";
|
||||
import { articleList } from "@/data/articles/index";
|
||||
import { useShowMore } from "@/hooks/useShowMore"
|
||||
import ShowMoreButton from "@/components/shared/ButtonShowMore"
|
||||
import ArticleItem from "@/components/shared/ArticleItem";
|
||||
|
||||
export default function ArticleList({ slug }: any) {
|
||||
|
||||
const { article } = categories.article.all_category;
|
||||
const categoryList = slug.children?.length > 0 ? slug.children : article
|
||||
|
||||
const articleData = articleList.find((item: any) => item.id === slug.id)?.list || [];
|
||||
const { displayData, hasMore, loadMore } = useShowMore(articleData, 12);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="article-categories-group bg-[#F5F8FF] flex justify-between relative overflow-auto whitespace-nowrap uppercase font-500 leading-[18px] text-[#828282] gap-5 lg:gap-1 no-scroll border-b border-[#C5CBD8]">
|
||||
{categoryList.map((item: any) => (
|
||||
<Link className={`${item.id === slug.id ? 'active' : ''}`}
|
||||
href={item.url}
|
||||
key={item.id}
|
||||
> {item.title} </Link>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{displayData.length == 0
|
||||
? (<p className="text-center font-600 uppercase mt-10 text-20"> Tin tức đang cập nhật ... ! </p>)
|
||||
: (
|
||||
<>
|
||||
<div className="article-holder grid lg:grid-cols-3 grid-cols-2 gap-4 lg:gap-6 my-5">
|
||||
{displayData.map((item: any) =>
|
||||
<ArticleItem
|
||||
key={item.id}
|
||||
item={item}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{hasMore &&
|
||||
<ShowMoreButton onClick={loadMore} />
|
||||
}
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -1,311 +1,29 @@
|
||||
export default function ArticleCategory({ slug }: { slug: string }) {
|
||||
return(
|
||||
<>
|
||||
<h1 className="absolute top-[-999px] z-[-1]"> Danh mục tin </h1>
|
||||
'use client';
|
||||
import { useEffect } from 'react';
|
||||
import ArticleList from "./article"
|
||||
import VideoList from "./video";
|
||||
|
||||
export default function ArticleCategory({ slug }: any) {
|
||||
useEffect(() => {
|
||||
document.body.style.background = '#F5F8FF';
|
||||
}, []);
|
||||
|
||||
const { type } = slug;
|
||||
|
||||
return (
|
||||
<> <h1 className="absolute top-[-999px] z-[-1]"> {slug.title} </h1>
|
||||
|
||||
<div className="article-page container !mt-8 mt-6">
|
||||
{/* <style>body{background: #F5F8FF}</style> */}
|
||||
<div className="article-categories-group bg-[#F5F8FF] flex justify-between relative overflow-auto whitespace-nowrap uppercase font-500 leading-[18px] text-[#828282] gap-5 lg:gap-1 no-scroll border-b border-[#C5CBD8]">
|
||||
<a href="" className="active">
|
||||
{" "}
|
||||
MÁY KHỎE - ĐẸP{" "}
|
||||
</a>
|
||||
<a href=""> TIN CÔNG NGHỆ </a>
|
||||
<a href=""> REVIEW SẢN PHẨM </a>
|
||||
<a href=""> BENCHMARKS </a>
|
||||
<a href=""> THỦ THUẬT </a>
|
||||
<a href=""> KHUYẾN MÃI </a>
|
||||
<a href=""> WIKI </a>
|
||||
<a href=""> tin game </a>
|
||||
</div>
|
||||
{/* Tin tức */}
|
||||
<div className="article-holder grid lg:grid-cols-3 grid-cols-2 gap-4 lg:gap-6 my-5">
|
||||
<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]" />
|
||||
<time> 23/4/2024 </time>
|
||||
<i className="w-[1.5px] h-[12px] bg-[#A0A5AC]" />
|
||||
<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]" />
|
||||
<time>23/4/2024</time>
|
||||
<i className="w-[1.5px] h-[12px] bg-[#A0A5AC]" />
|
||||
<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]" />
|
||||
<time>23/4/2024</time>
|
||||
<i className="w-[1.5px] h-[12px] bg-[#A0A5AC]" />
|
||||
<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]" />
|
||||
<time>23/4/2024</time>
|
||||
<i className="w-[1.5px] h-[12px] bg-[#A0A5AC]" />
|
||||
<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]" />
|
||||
<time>23/4/2024</time>
|
||||
<i className="w-[1.5px] h-[12px] bg-[#A0A5AC]" />
|
||||
<span>Mai Văn Học</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* Video */}
|
||||
<div className="article-holder article-video-holder grid lg:grid-cols-3 grid-cols-2 gap-4 lg:gap-6 my-5">
|
||||
<a
|
||||
href="https://www.youtube.com/watch?v=kGSYaCyNPvg"
|
||||
data-fancybox=""
|
||||
className="video-item"
|
||||
>
|
||||
<span className="item-img">
|
||||
<img
|
||||
src="https://hoanghapccdn.com/media/news/1241_pc_do_hoa_13900k_4070.jpg"
|
||||
alt="PC Đồ Họa Siêu Khỏe - Đẹp 13900K + VGA RTX 4070"
|
||||
width={120}
|
||||
height={66}
|
||||
/>
|
||||
<i className="bx bxs-play-circle" />
|
||||
</span>
|
||||
<span className="item-title">
|
||||
{" "}
|
||||
PC Đồ Họa Siêu Khỏe - Đẹp 13900K + VGA RTX 4070{" "}
|
||||
</span>
|
||||
</a>
|
||||
<a
|
||||
href="https://www.youtube.com/watch?v=kGSYaCyNPvg"
|
||||
data-fancybox=""
|
||||
className="video-item"
|
||||
>
|
||||
<span className="item-img">
|
||||
<img
|
||||
src="https://hoanghapccdn.com/media/news/1241_pc_do_hoa_13900k_4070.jpg"
|
||||
alt="PC Đồ Họa Siêu Khỏe - Đẹp 13900K + VGA RTX 4070"
|
||||
width={120}
|
||||
height={66}
|
||||
/>
|
||||
<i className="bx bxs-play-circle" />{" "}
|
||||
</span>
|
||||
<span className="item-title">
|
||||
PC Đồ Họa Siêu Khỏe - Đẹp 13900K + VGA RTX 4070
|
||||
</span>
|
||||
</a>
|
||||
<a
|
||||
href="https://www.youtube.com/watch?v=kGSYaCyNPvg"
|
||||
data-fancybox=""
|
||||
className="video-item"
|
||||
>
|
||||
<span className="item-img">
|
||||
<img
|
||||
src="https://hoanghapccdn.com/media/news/1241_pc_do_hoa_13900k_4070.jpg"
|
||||
alt="PC Đồ Họa Siêu Khỏe - Đẹp 13900K + VGA RTX 4070"
|
||||
width={120}
|
||||
height={66}
|
||||
/>
|
||||
<i className="bx bxs-play-circle" />{" "}
|
||||
</span>
|
||||
<span className="item-title">
|
||||
PC Đồ Họa Siêu Khỏe - Đẹp 13900K + VGA RTX 4070
|
||||
</span>
|
||||
</a>
|
||||
<a
|
||||
href="https://www.youtube.com/watch?v=kGSYaCyNPvg"
|
||||
data-fancybox=""
|
||||
className="video-item"
|
||||
>
|
||||
<span className="item-img">
|
||||
<img
|
||||
src="https://hoanghapccdn.com/media/news/1241_pc_do_hoa_13900k_4070.jpg"
|
||||
alt="PC Đồ Họa Siêu Khỏe - Đẹp 13900K + VGA RTX 4070"
|
||||
width={120}
|
||||
height={66}
|
||||
/>
|
||||
<i className="bx bxs-play-circle" />{" "}
|
||||
</span>
|
||||
<span className="item-title">
|
||||
PC Đồ Họa Siêu Khỏe - Đẹp 13900K + VGA RTX 4070
|
||||
</span>
|
||||
</a>
|
||||
<a
|
||||
href="https://www.youtube.com/watch?v=kGSYaCyNPvg"
|
||||
data-fancybox=""
|
||||
className="video-item"
|
||||
>
|
||||
<span className="item-img">
|
||||
<img
|
||||
src="https://hoanghapccdn.com/media/news/1241_pc_do_hoa_13900k_4070.jpg"
|
||||
alt="PC Đồ Họa Siêu Khỏe - Đẹp 13900K + VGA RTX 4070"
|
||||
width={120}
|
||||
height={66}
|
||||
/>
|
||||
<i className="bx bxs-play-circle" />{" "}
|
||||
</span>
|
||||
<span className="item-title">
|
||||
PC Đồ Họa Siêu Khỏe - Đẹp 13900K + VGA RTX 4070
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
{/* Paging */}
|
||||
<div className="my-10 flex flex-wrap items-center justify-center gap-4 leading-10 text-center text-16 font-500">
|
||||
<a
|
||||
href=""
|
||||
className="w-10 rounded-full border border-[#DDDDDD] hover:bg-[#004BA4] hover:text-white hover:border-transparent bg-[#004BA4] text-white border-transparent"
|
||||
>
|
||||
{" "}
|
||||
1{" "}
|
||||
</a>
|
||||
<a
|
||||
href=""
|
||||
className="w-10 rounded-full border border-[#DDDDDD] hover:bg-[#004BA4] hover:text-white hover:border-transparent"
|
||||
>
|
||||
{" "}
|
||||
2{" "}
|
||||
</a>{" "}
|
||||
<a
|
||||
href=""
|
||||
className="w-10 rounded-full border border-[#DDDDDD] hover:bg-[#004BA4] hover:text-white hover:border-transparent"
|
||||
>
|
||||
{" "}
|
||||
3{" "}
|
||||
</a>{" "}
|
||||
<a
|
||||
href=""
|
||||
className="w-10 rounded-full border border-[#DDDDDD] hover:bg-[#004BA4] hover:text-white hover:border-transparent"
|
||||
>
|
||||
{" "}
|
||||
4{" "}
|
||||
</a>
|
||||
</div>
|
||||
{
|
||||
type === 'article'
|
||||
&& <ArticleList slug={slug} />
|
||||
}
|
||||
|
||||
{
|
||||
type === 'video'
|
||||
&& <VideoList slug={slug} />
|
||||
}
|
||||
|
||||
</div>
|
||||
</>
|
||||
|
||||
|
||||
58
src/components/article/Category/video/index.tsx
Normal file
58
src/components/article/Category/video/index.tsx
Normal file
@@ -0,0 +1,58 @@
|
||||
'use client';
|
||||
import { Fancybox } from "@fancyapps/ui";
|
||||
import { useEffect } from "react";
|
||||
import { useShowMore } from "@/hooks/useShowMore"
|
||||
import { VideoData } from "@/data/articles/Video";
|
||||
import ShowMoreButton from "@/components/shared/ButtonShowMore"
|
||||
|
||||
export default function VideoList({ slug }: any) {
|
||||
|
||||
useEffect(() => {
|
||||
Fancybox.bind('[data-fancybox]', {});
|
||||
return () => Fancybox.destroy();
|
||||
}, []);
|
||||
|
||||
const { displayData, hasMore, loadMore } = useShowMore(VideoData.list, 12);
|
||||
|
||||
return (
|
||||
<>
|
||||
{displayData.length == 0
|
||||
? (<p className="text-center font-600 uppercase mt-10 text-20"> Tin tức đang cập nhật ... ! </p>)
|
||||
: (
|
||||
<>
|
||||
<div className="article-holder article-video-holder grid lg:grid-cols-3 grid-cols-2 gap-4 lg:gap-6 my-5">
|
||||
{
|
||||
displayData.map((item: any) =>
|
||||
<a
|
||||
key={item.id}
|
||||
href={item.video_code}
|
||||
data-fancybox=""
|
||||
className="video-item"
|
||||
rel="nofollow"
|
||||
>
|
||||
<span className="item-img">
|
||||
<img
|
||||
src={item.image.original}
|
||||
alt={item.title}
|
||||
width={120}
|
||||
height={66}
|
||||
/>
|
||||
<i className="bx bxs-play-circle" />
|
||||
</span>
|
||||
|
||||
<span className="item-title">
|
||||
{item.title}
|
||||
</span>
|
||||
</a>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
|
||||
{ hasMore &&
|
||||
<ShowMoreButton onClick={loadMore} />
|
||||
}
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -1,166 +1,124 @@
|
||||
import Link from "next/link";
|
||||
import { Swiper, SwiperSlide } from 'swiper/react';
|
||||
import { Pagination, Autoplay } from 'swiper/modules';
|
||||
|
||||
export default function Tiktok() {
|
||||
|
||||
return (
|
||||
<div className="article-tiktok-container py-8 lg:py-16">
|
||||
<div className="group-title flex items-center justify-between flex-wrap gap-4 mb-6">
|
||||
<h2 className="flex items-center m-0 leading-8 font-600 text-20 text-[#004BA4] gap-[10px] lg:gap-4 lg:text-[32px] lg:leading-10">
|
||||
<i
|
||||
className="lazy bg-no-repeat bg-center bg-[length:100%_100%] w-8 h-8 lg:w-12 lg:h-12"
|
||||
data-bg="url(images/logo-tiktok.png)"
|
||||
<i className="lazy bg-no-repeat bg-center bg-[length:100%_100%] w-8 h-8 lg:w-12 lg:h-12"
|
||||
style={{ backgroundImage: 'url(images/logo-tiktok.png)' }}
|
||||
/>
|
||||
<span> Tiktok Channel </span>
|
||||
</h2>
|
||||
|
||||
<div className="flex flex-wrap items-center justify-center text-center bg-[#DCE8FF] rounded-[16px_0_] leading-5 lg:leading-6 lg:text-[16px] gap-3 lg:w-[823px] w-full p-3 lg:p-4">
|
||||
<i className="icons icon-finger !w-6 !h-6 animation-wiggle" />
|
||||
<div className="lg:flex flex-wrap">
|
||||
<p className="m-0 mr-1">
|
||||
|
||||
Theo dõi kênh tiktok của Hoàng hà PC:
|
||||
</p>
|
||||
<a
|
||||
|
||||
<Link
|
||||
href="https://www.tiktok.com/@hoangha.pc"
|
||||
target="_blank"
|
||||
rel="nofollow"
|
||||
className="text-[#0678DB] font-600 table lg:text-[16px]"
|
||||
>
|
||||
|
||||
ORIGINAL SOUND - HOÀNG HÀ PC
|
||||
</a>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="swiper overflow-hidden" id="js-tiktok-slide">
|
||||
<div className="swiper-wrapper">
|
||||
<div className="swiper-slide">
|
||||
<a href="" target="_blank" rel="nofollow">
|
||||
<Swiper
|
||||
spaceBetween={16}
|
||||
slidesPerView={1.7}
|
||||
loop={true}
|
||||
autoplay={{
|
||||
delay: 3000,
|
||||
disableOnInteraction: false,
|
||||
}}
|
||||
modules={[Pagination, Autoplay]}
|
||||
speed={1000}
|
||||
breakpoints= {{
|
||||
414: {
|
||||
slidesPerView: 2
|
||||
},
|
||||
576: {
|
||||
slidesPerView: 3
|
||||
},
|
||||
768: {
|
||||
slidesPerView: 4
|
||||
},
|
||||
1024: {
|
||||
slidesPerView: 6
|
||||
}
|
||||
}}
|
||||
>
|
||||
<SwiperSlide>
|
||||
<Link href="https://www.tiktok.com/@hoangha.pc/video/7260350983039945985" rel="nofollow" target="_blank">
|
||||
<span className="block relative mb-2 rounded-[12px] overflow-hidden pb-[344px]">
|
||||
<img
|
||||
data-src="https://hoanghapccdn.com/media/lib/27-07-2023/don-hang-khach-vip.jpg"
|
||||
alt=""
|
||||
width={1}
|
||||
height={1}
|
||||
className="block lazy w-full absolute h-full object-cover"
|
||||
/>
|
||||
<img src="https://hoanghapccdn.com/media/lib/27-07-2023/don-hang-sieu-vip-pro.jpg" alt="tiktok video" width="1" height="1" className="block lazy w-full absolute h-full object-cover" />
|
||||
</span>
|
||||
<span className="block leading-[22px] font-600 text-16">
|
||||
Đơn hàng đặc biệt cho khách VIP
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
<div className="swiper-slide">
|
||||
<a href="" target="_blank" rel="nofollow">
|
||||
|
||||
<span className="block leading-[22px] font-600 text-16">Đơn hàng cho công ty VIP PRO</span>
|
||||
</Link>
|
||||
</SwiperSlide>
|
||||
|
||||
<SwiperSlide>
|
||||
<Link href="https://www.tiktok.com/@hoangha.pc/video/7259685093806034177" rel="nofollow" target="_blank">
|
||||
<span className="block relative mb-2 rounded-[12px] overflow-hidden pb-[344px]">
|
||||
<img
|
||||
data-src="https://hoanghapccdn.com/media/lib/27-07-2023/don-hang-khach-vip.jpg"
|
||||
alt=""
|
||||
width={1}
|
||||
height={1}
|
||||
className="block lazy w-full absolute h-full object-cover"
|
||||
/>
|
||||
<img src="https://hoanghapccdn.com/media/lib/27-07-2023/don-hang-khach-vip.jpg" alt="tiktok video" width="1" height="1" className="block lazy w-full absolute h-full object-cover" />
|
||||
</span>
|
||||
<span className="block leading-[22px] font-600 text-16">
|
||||
Đơn hàng đặc biệt cho khách VIP
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
<div className="swiper-slide">
|
||||
<a href="" target="_blank" rel="nofollow">
|
||||
|
||||
<span className="block leading-[22px] font-600 text-16"> Đơn hàng đặc biệt cho khách vip </span>
|
||||
</Link>
|
||||
</SwiperSlide>
|
||||
|
||||
<SwiperSlide>
|
||||
<Link href="https://www.tiktok.com/@hoangha.pc/video/7259272220093041926" rel="nofollow" target="_blank">
|
||||
<span className="block relative mb-2 rounded-[12px] overflow-hidden pb-[344px]">
|
||||
<img
|
||||
data-src="https://hoanghapccdn.com/media/lib/27-07-2023/don-hang-khach-vip.jpg"
|
||||
alt=""
|
||||
width={1}
|
||||
height={1}
|
||||
className="block lazy w-full absolute h-full object-cover"
|
||||
/>
|
||||
<img src="https://hoanghapccdn.com/media/lib/27-07-2023/don-pc-200-trieu.jpg" alt="tiktok video" width="1" height="1" className="block lazy w-full absolute h-full object-cover" />
|
||||
</span>
|
||||
<span className="block leading-[22px] font-600 text-16">
|
||||
Đơn hàng đặc biệt cho khách VIP
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
<div className="swiper-slide">
|
||||
<a href="" target="_blank" rel="nofollow">
|
||||
|
||||
<span className="block leading-[22px] font-600 text-16"> Đơn PC hơn 200 củ </span>
|
||||
</Link>
|
||||
</SwiperSlide>
|
||||
|
||||
<SwiperSlide>
|
||||
<Link href="https://www.tiktok.com/@hoangha.pc/video/7256640817752820997" rel="nofollow" target="_blank">
|
||||
<span className="block relative mb-2 rounded-[12px] overflow-hidden pb-[344px]">
|
||||
<img
|
||||
data-src="https://hoanghapccdn.com/media/lib/27-07-2023/don-hang-khach-vip.jpg"
|
||||
alt=""
|
||||
width={1}
|
||||
height={1}
|
||||
className="block lazy w-full absolute h-full object-cover"
|
||||
/>
|
||||
<img src="https://hoanghapccdn.com/media/lib/27-07-2023/don-pc-300-trieu.jpg" alt="tiktok video" width="1" height="1" className="block lazy w-full absolute h-full object-cover" />
|
||||
</span>
|
||||
<span className="block leading-[22px] font-600 text-16">
|
||||
Đơn hàng đặc biệt cho khách VIP
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
<div className="swiper-slide">
|
||||
<a href="" target="_blank" rel="nofollow">
|
||||
|
||||
<span className="block leading-[22px] font-600 text-16"> Đơn hàng hơn 300 củ có gì? </span>
|
||||
</Link>
|
||||
</SwiperSlide>
|
||||
|
||||
<SwiperSlide>
|
||||
<Link href="https://www.tiktok.com/@hoangha.pc/video/7249589730000522501" rel="nofollow" target="_blank">
|
||||
<span className="block relative mb-2 rounded-[12px] overflow-hidden pb-[344px]">
|
||||
<img
|
||||
data-src="https://hoanghapccdn.com/media/lib/27-07-2023/don-hang-khach-vip.jpg"
|
||||
alt=""
|
||||
width={1}
|
||||
height={1}
|
||||
className="block lazy w-full absolute h-full object-cover"
|
||||
/>
|
||||
<img src="https://hoanghapccdn.com/media/lib/27-07-2023/pc-dau-than.jpg" alt="tiktok video" width="1" height="1" className="block lazy w-full absolute h-full object-cover" />
|
||||
</span>
|
||||
<span className="block leading-[22px] font-600 text-16">
|
||||
Đơn hàng đặc biệt cho khách VIP
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
<div className="swiper-slide">
|
||||
<a href="" target="_blank" rel="nofollow">
|
||||
|
||||
<span className="block leading-[22px] font-600 text-16"> PC Full trắng vừa đẹp vừa khỏe </span>
|
||||
</Link>
|
||||
</SwiperSlide>
|
||||
|
||||
<SwiperSlide>
|
||||
<Link href="https://www.tiktok.com/@hoangha.pc/video/7245136755375049989" rel="nofollow" target="_blank">
|
||||
<span className="block relative mb-2 rounded-[12px] overflow-hidden pb-[344px]">
|
||||
<img
|
||||
data-src="https://hoanghapccdn.com/media/lib/27-07-2023/don-hang-khach-vip.jpg"
|
||||
alt=""
|
||||
width={1}
|
||||
height={1}
|
||||
className="block lazy w-full absolute h-full object-cover"
|
||||
/>
|
||||
<img src="https://hoanghapccdn.com/media/lib/27-07-2023/pc-80-trieu-co-gi.jpg" alt="tiktok video" width="1" height="1" className="block lazy w-full absolute h-full object-cover" />
|
||||
</span>
|
||||
<span className="block leading-[22px] font-600 text-16">
|
||||
Đơn hàng đặc biệt cho khách VIP
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
<div className="swiper-slide">
|
||||
<a href="" target="_blank" rel="nofollow">
|
||||
<span className="block relative mb-2 rounded-[12px] overflow-hidden pb-[344px]">
|
||||
<img
|
||||
data-src="https://hoanghapccdn.com/media/lib/27-07-2023/don-hang-khach-vip.jpg"
|
||||
alt=""
|
||||
width={1}
|
||||
height={1}
|
||||
className="block lazy w-full absolute h-full object-cover"
|
||||
/>
|
||||
</span>
|
||||
<span className="block leading-[22px] font-600 text-16">
|
||||
Đơn hàng đặc biệt cho khách VIP
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
<div className="swiper-slide">
|
||||
<a href="" target="_blank" rel="nofollow">
|
||||
<span className="block relative mb-2 rounded-[12px] overflow-hidden pb-[344px]">
|
||||
<img
|
||||
data-src="https://hoanghapccdn.com/media/lib/27-07-2023/don-hang-khach-vip.jpg"
|
||||
alt=""
|
||||
width={1}
|
||||
height={1}
|
||||
className="block lazy w-full absolute h-full object-cover"
|
||||
/>
|
||||
</span>
|
||||
<span className="block leading-[22px] font-600 text-16">
|
||||
Đơn hàng đặc biệt cho khách VIP
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<span className="block leading-[22px] font-600 text-16"> PC 80 củ có gì? </span>
|
||||
</Link>
|
||||
</SwiperSlide>
|
||||
</Swiper>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -2,7 +2,7 @@ import Link from "next/link";
|
||||
import { useState, useEffect, useMemo } from "react";
|
||||
import { VideoData } from "@/data/articles/Video";
|
||||
|
||||
export default function Video() {
|
||||
export default function Video( {item} : any ) {
|
||||
const { total, list } = VideoData;
|
||||
const [active, setActive] = useState<number | null>(null);
|
||||
const [url, setUrl] = useState<string>("");
|
||||
@@ -31,7 +31,6 @@ export default function Video() {
|
||||
return null;
|
||||
}, [url]);
|
||||
|
||||
|
||||
return (list.length > 0 &&
|
||||
<div className="article-video-container lg:flex flex-wrap gap-4 mt-16">
|
||||
<div className="lg:w-[732px] video-holder">
|
||||
@@ -48,14 +47,13 @@ export default function Video() {
|
||||
<i className="w-[18px] h-[18px] lg:w-6 lg:h-6 lazy bg-no-repeat bg-center bg-[length:100%_100%]"
|
||||
style={{ backgroundImage: 'url(/images/icon-playlist.png)' }}
|
||||
/>
|
||||
<Link href="/video"> Trending video </Link>
|
||||
<Link href={item[0].url}> Trending video </Link>
|
||||
</p>
|
||||
|
||||
<div className="h-[385px] p-4 pr-1 relative">
|
||||
<div className="h-full overflow-auto flex flex-col gap-4">
|
||||
{list.map((item: any) =>
|
||||
<button
|
||||
type="button"
|
||||
<button type="button"
|
||||
key={item.id}
|
||||
onClick={() => {
|
||||
setActive(item.id);
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
'use client';
|
||||
import Link from "next/link";
|
||||
import { useEffect } from 'react';
|
||||
import useScrollSpy from "@/hooks/useScrollSpy";
|
||||
import { articleList } from "@/data/articles";
|
||||
import { categories } from "@/data/categories";
|
||||
import useScrollSpy from "@/hooks/useScrollSpy";
|
||||
|
||||
import TopArticleList from "./TopArticleList";
|
||||
import ArticleCategories from "./ArticleCategories";
|
||||
import Video from "./Video"
|
||||
@@ -12,12 +13,9 @@ import Tiktok from "./Tiktok";
|
||||
export default function ArticleHome() {
|
||||
const {
|
||||
article,
|
||||
video,
|
||||
job
|
||||
video
|
||||
} = categories.article.all_category;
|
||||
|
||||
console.log(video, job)
|
||||
|
||||
const top_article_list = articleList
|
||||
.flatMap(item => item.list)
|
||||
.filter(item => item.is_featured == 1)
|
||||
@@ -44,7 +42,7 @@ export default function ArticleHome() {
|
||||
|
||||
<div className="article-categories-group bg-[#F5F8FF] sticky top-[68px] lg:top-[76px] left-0 right-0 z-[2] pt-5">
|
||||
<div className="container flex justify-between relative overflow-auto whitespace-nowrap uppercase font-500 leading-[18px] text-[#828282] gap-5 lg:gap-1 no-scroll border-b border-[#C5CBD8]">
|
||||
{article.map((item) => (
|
||||
{categories.article.all_category.article.map((item:any) => (
|
||||
<Link className="js-category-tab"
|
||||
href={`#js-category-${item.id}`}
|
||||
key={item.id}
|
||||
@@ -68,7 +66,9 @@ export default function ArticleHome() {
|
||||
</div>
|
||||
|
||||
<div className="container">
|
||||
<Video />
|
||||
{video.length > 0 &&
|
||||
<Video item={video} />
|
||||
}
|
||||
|
||||
<Tiktok />
|
||||
</div>
|
||||
|
||||
@@ -1,14 +1,24 @@
|
||||
export default function ArticleDetail({ slug }: { slug: string }) {
|
||||
return(
|
||||
'use client';
|
||||
import Link from "next/link";
|
||||
import parse from "html-react-parser";
|
||||
import { useEffect } from 'react';
|
||||
import { formatArticleTime } from "@/lib/utils";
|
||||
import ArticleItem from "@/components/shared/ArticleItem";
|
||||
|
||||
export default function ArticleDetail({ slug }: any) {
|
||||
useEffect(() => {
|
||||
document.body.style.background = '#ffffff';
|
||||
}, []);
|
||||
|
||||
const time = slug.article_time || slug.lastUpdate;
|
||||
|
||||
return (
|
||||
<>
|
||||
<link
|
||||
href="https://cdn.boxicons.com/fonts/brands/boxicons-brands.min.css"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<link href="https://cdn.boxicons.com/fonts/brands/boxicons-brands.min.css" rel="stylesheet" />
|
||||
|
||||
<div className="container !mt-8 mt-6">
|
||||
{/* <style> body{background: #fff;} </style> */}
|
||||
<div className="article-detail-page max-w-[824px] m-auto my-8">
|
||||
<a
|
||||
<Link
|
||||
href=""
|
||||
target="_blank"
|
||||
rel="nofollow"
|
||||
@@ -22,197 +32,79 @@ export default function ArticleDetail({ slug }: { slug: string }) {
|
||||
<span className="text-[#34A853]">l</span>
|
||||
<span className="text-[#EA4335]">e</span>
|
||||
<span className="text-[#5F6368]"> News </span>
|
||||
</a>
|
||||
</Link>
|
||||
|
||||
<h1 className="font-600 text-[#004BA4] text-20 leading-6 lg:leading-10 lg:text-[32px] mb-3">
|
||||
{" "}
|
||||
{"{"}
|
||||
{"{"} page.article_detail.title {"}"}
|
||||
{"}"}{" "}
|
||||
{slug.title}
|
||||
</h1>
|
||||
|
||||
<div className="lg:text-[16px] lg:leading-[22px] flex items-center gap-1 mb-6 lg:mb-8">
|
||||
<i className="icons icon-time mr-1" />
|
||||
<span> Thứ sáu 25/07/2025 </span>
|
||||
<span> {formatArticleTime(time)} </span>
|
||||
<span>|</span>
|
||||
<a href=""> Mai Văn Học </a>
|
||||
<a href="/author/mai-van-hoc"> {slug.author} </a>
|
||||
</div>
|
||||
<div className="article-content lg:leading-6 lg:text-[18px]">
|
||||
<p>
|
||||
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Aspernatur
|
||||
quaerat vero itaque voluptatum? Repellendus laudantium est doloribus
|
||||
saepe accusantium, illo numquam ullam deserunt expedita repudiandae
|
||||
ipsam libero, temporibus soluta eius.
|
||||
</p>
|
||||
|
||||
<div className="article-content lg:leading-5 lg:text-[16px] text-justify">
|
||||
{parse(slug.content)}
|
||||
</div>
|
||||
|
||||
<div className="flex items-center flex-wrap lg:gap-[30px] gap-5 mb-8">
|
||||
<p className="m-0">SHARE</p>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
<a
|
||||
<Link
|
||||
href=""
|
||||
rel="nofollow"
|
||||
target="_blank"
|
||||
className="bx bx-share w-[42px] h-[42px] !flex items-center justify-center rounded-full bg-[#0678DB] text-white text-center text-[21px] transition-all duration-300 relative bottom-0 hover:bottom-[5px]"
|
||||
/>
|
||||
<a
|
||||
></Link>
|
||||
<Link
|
||||
href=""
|
||||
rel="nofollow"
|
||||
target="_blank"
|
||||
className="bxl bx-facebook w-[42px] h-[42px] !flex items-center justify-center rounded-full bg-[#0678DB] text-white text-center text-[21px] transition-all duration-300 relative bottom-0 hover:bottom-[5px]"
|
||||
/>
|
||||
<a
|
||||
></Link>
|
||||
<Link
|
||||
href=""
|
||||
rel="nofollow"
|
||||
target="_blank"
|
||||
className="bxl bx-youtube w-[42px] h-[42px] !flex items-center justify-center rounded-full bg-[#0678DB] text-white text-center text-[21px] transition-all duration-300 relative bottom-0 hover:bottom-[5px]"
|
||||
/>
|
||||
<a
|
||||
></Link>
|
||||
<Link
|
||||
href=""
|
||||
rel="nofollow"
|
||||
target="_blank"
|
||||
className="bxl bx-instagram-alt w-[42px] h-[42px] !flex items-center justify-center rounded-full bg-[#0678DB] text-white text-center text-[21px] transition-all duration-300 relative bottom-0 hover:bottom-[5px]"
|
||||
/>
|
||||
<a
|
||||
></Link>
|
||||
<Link
|
||||
href=""
|
||||
rel="nofollow"
|
||||
target="_blank"
|
||||
className="bxl bx-tiktok w-[42px] h-[42px] !flex items-center justify-center rounded-full bg-[#0678DB] text-white text-center text-[21px] transition-all duration-300 relative bottom-0 hover:bottom-[5px]"
|
||||
/>
|
||||
></Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{slug.related.article &&
|
||||
<div className="mt-10 lg:mt-12">
|
||||
<p className="font-600 text-[32px] leading-10 mb-6 lg:text-[40px] lg:leading-12 lg:mb-8">
|
||||
{" "}
|
||||
Bài viết liên quan{" "}
|
||||
Bài viết liên quan
|
||||
</p>
|
||||
{/* Limit: 4 */}
|
||||
|
||||
<div className="grid grid-cols-2 gap-4 lg:grid-cols-4 lg: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}
|
||||
{
|
||||
slug.related.article.slice(0, 4).map((item: any) =>
|
||||
<ArticleItem
|
||||
item={item}
|
||||
key={item.id}
|
||||
/>
|
||||
</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]" />
|
||||
<time>23/4/2024</time>
|
||||
<i className="w-[1.5px] h-[12px] bg-[#A0A5AC]" />
|
||||
<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]" />
|
||||
<time>23/4/2024</time>
|
||||
<i className="w-[1.5px] h-[12px] bg-[#A0A5AC]" />
|
||||
<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]" />
|
||||
<time>23/4/2024</time>
|
||||
<i className="w-[1.5px] h-[12px] bg-[#A0A5AC]" />
|
||||
<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]" />
|
||||
<time>23/4/2024</time>
|
||||
<i className="w-[1.5px] h-[12px] bg-[#A0A5AC]" />
|
||||
<span>Mai Văn Học</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
</>
|
||||
|
||||
)
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
import { Swiper, SwiperSlide } from 'swiper/react';
|
||||
import { Navigation, Pagination, Autoplay } from 'swiper/modules';
|
||||
import { categories } from "@/data/categories"
|
||||
import { productList } from '@/data/productList';
|
||||
import { productList } from '@/data/products/productList';
|
||||
import CategoryIcon from "./CategoryIcon"
|
||||
import ProductItem from "@/components/shared/ProductItem"
|
||||
import Link from 'next/link';
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
'use client';
|
||||
import { useState, useEffect } from "react";
|
||||
import { useState } from "react";
|
||||
|
||||
export default function FAQ({ faq }: any) {
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { productCategory } from "@/data/productCategory";
|
||||
import { productCategory } from "@/data/products/productCategory";
|
||||
import { productList } from "@/data/products/productList";
|
||||
|
||||
import ProductFilter from "./filter";
|
||||
import Static from "./static";
|
||||
@@ -6,7 +7,7 @@ import FAQ from "./faq";
|
||||
import Banner from "./banner";
|
||||
import SortByCollection from "./sort";
|
||||
import ProductList from "./productList";
|
||||
import { productList } from "@/data/productList";
|
||||
|
||||
|
||||
export default function ProductCategory({ slug }: any) {
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
'use client';
|
||||
import { useState } from "react";
|
||||
import { productList } from "@/data/productList";
|
||||
import { productList } from "@/data/products/productList";
|
||||
import ProductItem from "@/components/shared/ProductItem";
|
||||
|
||||
const PRODUCT_PER_PAGE = 30;
|
||||
|
||||
@@ -8,15 +8,18 @@ import CommentList from "./CommentList";
|
||||
export default function Comment() {
|
||||
const [star, setStar] = useState<number | null>(null);
|
||||
|
||||
const productComment = CommentData.list.filter( (item:any) => item.item_type === "product" );
|
||||
|
||||
const filteredComments = useMemo(() => {
|
||||
if (star === null) return CommentData.list;
|
||||
return CommentData.list.filter(item => Number(item.rate) === star);
|
||||
if (star === null) return productComment;
|
||||
return productComment.filter(item => Number(item.rate) === star);
|
||||
}, [star]);
|
||||
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className="flex items-center justify-between leading-8 gap-2 mb-4">
|
||||
<p className="m-0 text-18 font-500"> {CommentData.list.length} Bình luận </p>
|
||||
<p className="m-0 text-18 font-500"> {filteredComments.length} Bình luận </p>
|
||||
|
||||
<div className="flex flex-wrap gap-2 text-14 font-500 pd-comment-btn">
|
||||
<button type="button"
|
||||
|
||||
@@ -4,7 +4,6 @@ import { useState } from 'react'
|
||||
import dynamic from 'next/dynamic'
|
||||
import { Swiper, SwiperSlide } from 'swiper/react'
|
||||
import { Navigation } from 'swiper/modules'
|
||||
import Link from 'next/link'
|
||||
|
||||
const PhotoSwipeImage = dynamic(
|
||||
() => import('./PhotoSwipeImage'),
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import parse from 'html-react-parser';
|
||||
import { formatPrice } from "@/lib/utils";
|
||||
|
||||
import ProductImage from "./images";
|
||||
import Static from "./static";
|
||||
import ProductDescription from "./description"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import { useEffect, useState, useMemo } from "react";
|
||||
import { Swiper, SwiperSlide } from 'swiper/react';
|
||||
import { Navigation, Pagination, Autoplay } from 'swiper/modules';
|
||||
import { ProductHistory } from "@/data/productHistory";
|
||||
import { ProductHistory } from "@/data/products/productHistory";
|
||||
import ProductItem from "@/components/shared/ProductItem"
|
||||
|
||||
export default function ProductTab({ item }: any) {
|
||||
|
||||
@@ -7,6 +7,7 @@ import ReviewList from "./ReviewList";
|
||||
export default function Review( {item} : any ) {
|
||||
|
||||
const [ show, setShow ] = useState(false);
|
||||
const productReview = item.list.filter( (item:any) => item.item_type === "product" );
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -34,9 +35,9 @@ export default function Review( {item} : any ) {
|
||||
<ReviewForm />
|
||||
</div>
|
||||
|
||||
{item.list.length > 0 &&
|
||||
{productReview.length > 0 &&
|
||||
<div className="text-14 leading-[18px] mt-4">
|
||||
<ReviewList item={item.list}/>
|
||||
<ReviewList item={productReview}/>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
482
src/data/articleDetail/index.tsx
Normal file
482
src/data/articleDetail/index.tsx
Normal file
File diff suppressed because one or more lines are too long
@@ -240,7 +240,7 @@ export const categories = {
|
||||
parentId: 0,
|
||||
isParent: 0,
|
||||
item_count: 6,
|
||||
type: "article",
|
||||
type: "video",
|
||||
title: "Trending video",
|
||||
url: "/trending-video",
|
||||
summary: "",
|
||||
@@ -255,7 +255,7 @@ export const categories = {
|
||||
parentId: 0,
|
||||
isParent: 0,
|
||||
item_count: 1,
|
||||
type: "article",
|
||||
type: "job",
|
||||
title: "Kinh doanh online",
|
||||
url: "/kinh-doanh-online",
|
||||
summary: "",
|
||||
@@ -267,7 +267,7 @@ export const categories = {
|
||||
parentId: 0,
|
||||
isParent: 0,
|
||||
item_count: 0,
|
||||
type: "article",
|
||||
type: "job",
|
||||
title: "Truyền thông nội bộ",
|
||||
url: "/truyen-thong-noi-bo",
|
||||
summary: "",
|
||||
@@ -279,7 +279,7 @@ export const categories = {
|
||||
parentId: 0,
|
||||
isParent: 0,
|
||||
item_count: 3,
|
||||
type: "article",
|
||||
type: "job",
|
||||
title: "Kỹ thuật máy tính",
|
||||
url: "/ky-thuat-may-tinh",
|
||||
summary: "",
|
||||
@@ -291,7 +291,7 @@ export const categories = {
|
||||
parentId: 0,
|
||||
isParent: 0,
|
||||
item_count: 2,
|
||||
type: "article",
|
||||
type: "job",
|
||||
title: "Tài chính kế toán",
|
||||
url: "/tai-chinh-ke-toan",
|
||||
summary: "",
|
||||
@@ -303,7 +303,7 @@ export const categories = {
|
||||
parentId: 0,
|
||||
isParent: 0,
|
||||
item_count: 3,
|
||||
type: "article",
|
||||
type: "job",
|
||||
title: "Marketing",
|
||||
url: "/marketing",
|
||||
summary: "",
|
||||
@@ -315,7 +315,7 @@ export const categories = {
|
||||
parentId: 0,
|
||||
isParent: 0,
|
||||
item_count: 1,
|
||||
type: "article",
|
||||
type: "job",
|
||||
title: "Nhân sự",
|
||||
url: "/nhan-su",
|
||||
summary: "",
|
||||
|
||||
@@ -5,6 +5,77 @@ export const CommentData = {
|
||||
"total": 0,
|
||||
},
|
||||
"list": [
|
||||
{
|
||||
"id": "1",
|
||||
"item_type": "article",
|
||||
"item_id": "2",
|
||||
"people_like_count": "0",
|
||||
"people_dislike_count": "0",
|
||||
"reply_count": "0",
|
||||
"is_user_admin": "0",
|
||||
"user_avatar": "",
|
||||
"user_name": "VU THANH CHUNG - S\u0110T: 0988358888",
|
||||
"rate": "5",
|
||||
"title": "HHPC CORE i7 14700KF | 64GB | NVIDIA RTX 5070 Ti 16G",
|
||||
"content": "Test review article ",
|
||||
"files": [],
|
||||
"approved": "0",
|
||||
"post_time": "1766984975",
|
||||
"counter": 1,
|
||||
"new_replies": [
|
||||
{
|
||||
"id": "2",
|
||||
"item_type": "article",
|
||||
"item_id": "6434",
|
||||
"people_like_count": "0",
|
||||
"people_dislike_count": "0",
|
||||
"reply_count": "1",
|
||||
"is_user_admin": "0",
|
||||
"user_avatar": "",
|
||||
"user_name": "hura test - S\u0110T: 0987654321",
|
||||
"rate": "2",
|
||||
"title": "HuraSoft - S\u1ea3n ph\u1ea9m test (Kh\u00f4ng x\u00f3a)",
|
||||
"content": "Test reply article 1",
|
||||
"files": [],
|
||||
"approved": "1",
|
||||
"post_time": "1760330892",
|
||||
"counter": 5,
|
||||
"new_replies": [
|
||||
{
|
||||
"id": 742,
|
||||
"comment_id": 8760,
|
||||
"user_avatar": "0",
|
||||
"user_name": "Hurasoft \u0110\u1ee9c",
|
||||
"is_user_admin": 1,
|
||||
"people_like_count": 0,
|
||||
"approved": 1,
|
||||
"people_dislike_count": 0,
|
||||
"content": "admin test",
|
||||
"post_time": 1760331038
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "8757",
|
||||
"item_type": "article",
|
||||
"item_id": "6270",
|
||||
"people_like_count": "0",
|
||||
"people_dislike_count": "0",
|
||||
"reply_count": "0",
|
||||
"is_user_admin": "0",
|
||||
"user_avatar": "",
|
||||
"user_name": "Ch\u1ecbu - S\u1ed1 \u0111t : 0938553437",
|
||||
"rate": "5",
|
||||
"title": "\u0110\u00e1nh gi\u00e1 s\u1ea3n ph\u1ea9m Fan Xigmatek Infinity Pro 2 RGB Reverse",
|
||||
"content": "5 sao",
|
||||
"files": [],
|
||||
"approved": "0",
|
||||
"post_time": "1759639059",
|
||||
"counter": 6,
|
||||
"new_replies": []
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "10187",
|
||||
"item_type": "product",
|
||||
|
||||
@@ -19,6 +19,77 @@ export const ReviewData = {
|
||||
"total": 20,
|
||||
},
|
||||
"list": [
|
||||
{
|
||||
"id": "1",
|
||||
"item_type": "article",
|
||||
"item_id": "2",
|
||||
"people_like_count": "0",
|
||||
"people_dislike_count": "0",
|
||||
"reply_count": "0",
|
||||
"is_user_admin": "0",
|
||||
"user_avatar": "",
|
||||
"user_name": "VU THANH CHUNG - S\u0110T: 0988358888",
|
||||
"rate": "5",
|
||||
"title": "HHPC CORE i7 14700KF | 64GB | NVIDIA RTX 5070 Ti 16G",
|
||||
"content": "Test review article ",
|
||||
"files": [],
|
||||
"approved": "0",
|
||||
"post_time": "1766984975",
|
||||
"counter": 1,
|
||||
"new_replies": [
|
||||
{
|
||||
"id": "2",
|
||||
"item_type": "article",
|
||||
"item_id": "6434",
|
||||
"people_like_count": "0",
|
||||
"people_dislike_count": "0",
|
||||
"reply_count": "1",
|
||||
"is_user_admin": "0",
|
||||
"user_avatar": "",
|
||||
"user_name": "hura test - S\u0110T: 0987654321",
|
||||
"rate": "2",
|
||||
"title": "HuraSoft - S\u1ea3n ph\u1ea9m test (Kh\u00f4ng x\u00f3a)",
|
||||
"content": "Test reply article 1",
|
||||
"files": [],
|
||||
"approved": "1",
|
||||
"post_time": "1760330892",
|
||||
"counter": 5,
|
||||
"new_replies": [
|
||||
{
|
||||
"id": 742,
|
||||
"comment_id": 8760,
|
||||
"user_avatar": "0",
|
||||
"user_name": "Hurasoft \u0110\u1ee9c",
|
||||
"is_user_admin": 1,
|
||||
"people_like_count": 0,
|
||||
"approved": 1,
|
||||
"people_dislike_count": 0,
|
||||
"content": "admin test",
|
||||
"post_time": 1760331038
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "8757",
|
||||
"item_type": "article",
|
||||
"item_id": "6270",
|
||||
"people_like_count": "0",
|
||||
"people_dislike_count": "0",
|
||||
"reply_count": "0",
|
||||
"is_user_admin": "0",
|
||||
"user_avatar": "",
|
||||
"user_name": "Ch\u1ecbu - S\u1ed1 \u0111t : 0938553437",
|
||||
"rate": "5",
|
||||
"title": "\u0110\u00e1nh gi\u00e1 s\u1ea3n ph\u1ea9m Fan Xigmatek Infinity Pro 2 RGB Reverse",
|
||||
"content": "5 sao",
|
||||
"files": [],
|
||||
"approved": "0",
|
||||
"post_time": "1759639059",
|
||||
"counter": 6,
|
||||
"new_replies": []
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "8768",
|
||||
"item_type": "product",
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// src/lib/articlePage.ts
|
||||
import { categories } from "@/data/categories";
|
||||
import { articleList } from "@/data/articles";
|
||||
import { ArticleDetail } from "@/data/articleDetail"
|
||||
|
||||
export type ArticleResult =
|
||||
| { type: "article_home"; data: any }
|
||||
@@ -12,28 +13,54 @@ export function resolveArticlePage(slug: string): ArticleResult | null {
|
||||
|
||||
// HOME
|
||||
if (url === "/tin-tuc") {
|
||||
return { type: "article_home", data: null };
|
||||
return {
|
||||
type: "article_home",
|
||||
data : null
|
||||
};
|
||||
}
|
||||
|
||||
// CATEGORY
|
||||
const cats = categories.article.all_category.article;
|
||||
for (const parent of cats) {
|
||||
const { article, job, video } = categories.article.all_category;
|
||||
const allCategories = [...article, ...job, ...video];
|
||||
|
||||
for (const parent of allCategories) {
|
||||
if (parent.url === url) {
|
||||
return { type: "article_category", data: parent };
|
||||
return {
|
||||
type: "article_category",
|
||||
data: parent
|
||||
};
|
||||
}
|
||||
|
||||
for (const child of parent.children ?? []) {
|
||||
if (child.url === url) {
|
||||
return { type: "article_category", data: child };
|
||||
return {
|
||||
type: "article_category",
|
||||
data: child
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// DETAIL
|
||||
const allArticles = articleList.flatMap(article => article.list);
|
||||
for (const article of allArticles) {
|
||||
if (article.url === url) {
|
||||
return { type: "article_detail", data: { slug } };
|
||||
const detail = articleList
|
||||
.flatMap(article => article.list)
|
||||
.find((a: any) => a.url === url);
|
||||
if(detail) {
|
||||
const data = {
|
||||
...detail,
|
||||
content : ArticleDetail.content,
|
||||
author : ArticleDetail.author,
|
||||
image_list : ArticleDetail.image_list,
|
||||
related : ArticleDetail.related,
|
||||
tag_list : ArticleDetail.tag_list,
|
||||
}
|
||||
|
||||
return {
|
||||
type: "article_detail",
|
||||
data
|
||||
};
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// hoanghapc/src/lib/productPage.ts
|
||||
import { categories } from "@/data/categories";
|
||||
import { productList } from "@/data/productList";
|
||||
import { productDetail } from "@/data/productDetail"
|
||||
import { productList } from "@/data/products/productList";
|
||||
import { productDetail } from "@/data/products/productDetail"
|
||||
|
||||
export type ProductResult =
|
||||
| { type: "product_category"; data: any }
|
||||
|
||||
@@ -15,8 +15,8 @@ export function findBySlug(slug?: string): SlugResult | null {
|
||||
if (product) return product;
|
||||
|
||||
// ARTICLE
|
||||
const articler = resolveArticlePage(slug);
|
||||
if (articler) return articler;
|
||||
const article = resolveArticlePage(slug);
|
||||
if (article) return article;
|
||||
|
||||
// 404
|
||||
return null;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Add tất cả sp trong data product vào 1 mảng
|
||||
import { productList } from '@/data/productList';
|
||||
import { productList } from '@/data/products/productList';
|
||||
|
||||
export function getAllProducts() {
|
||||
return productList.flatMap((group: any) => group.list);
|
||||
|
||||
@@ -60,7 +60,7 @@ body{min-width:1248px;background:#E8ECF6}
|
||||
.icon-gift{background-position:-40px -159px}
|
||||
.icon-card{background-position:-5px -193px}
|
||||
.icon-flame{background-position:-40px -194px}
|
||||
.icon-goTop{position:fixed;bottom:100px;right:10px;width:48px;height:48px;line-height:46px;border-radius:50%;border:1px solid #E0E0E0;color:#fff;background:#3947b9;font-size:28px;z-index:8;}
|
||||
.icon-goTop{position:fixed;bottom:100px;right:10px;width:48px;height:48px;line-height:46px;border-radius:50%;border:1px solid #E0E0E0;color:#fff;background:#3947b9;font-size:28px;z-index:10;}
|
||||
.icon-finger{background-position:-155px -222px}
|
||||
.inherit,.art-item .art-title *,.p-item .p-name *,.deal-item .deal-name *{font-weight:inherit!important;font-size:inherit!important;line-height:inherit!important;margin:0}
|
||||
.custom-dots .swiper-pagination-bullet{width:20px;height:6px;border:2px solid rgba(255,255,255,0.7);border-radius:8px 0 8px 0;background:transparent;opacity:1;margin:0 3px!important;transition:.15s all}
|
||||
|
||||
Reference in New Issue
Block a user