Fix blog tables (remark-gfm), update portfolio images, fix dropdown hover issues, remove contact form
|
Before Width: | Height: | Size: 682 KiB |
|
Before Width: | Height: | Size: 278 KiB |
|
Before Width: | Height: | Size: 748 KiB |
|
Before Width: | Height: | Size: 471 KiB |
|
Before Width: | Height: | Size: 868 KiB |
|
Before Width: | Height: | Size: 285 KiB |
BIN
homepage.png
|
Before Width: | Height: | Size: 285 KiB |
|
Before Width: | Height: | Size: 852 KiB |
|
Before Width: | Height: | Size: 336 KiB |
@@ -6,9 +6,9 @@ import path from 'path';
|
|||||||
import matter from 'gray-matter';
|
import matter from 'gray-matter';
|
||||||
import { remark } from 'remark';
|
import { remark } from 'remark';
|
||||||
import html from 'remark-html';
|
import html from 'remark-html';
|
||||||
|
import gfm from 'remark-gfm';
|
||||||
interface Props {
|
interface Props {
|
||||||
params: { slug: string };
|
params: Promise<{ slug: string }>;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getPost(slug: string) {
|
async function getPost(slug: string) {
|
||||||
@@ -23,24 +23,32 @@ async function getPost(slug: string) {
|
|||||||
const { data, content } = matter(fileContent);
|
const { data, content } = matter(fileContent);
|
||||||
|
|
||||||
const processedContent = await remark()
|
const processedContent = await remark()
|
||||||
|
.use(gfm)
|
||||||
.use(html, { sanitize: false })
|
.use(html, { sanitize: false })
|
||||||
.process(content);
|
.process(content);
|
||||||
const contentHtml = processedContent.toString();
|
const contentHtml = processedContent.toString();
|
||||||
|
|
||||||
|
// Support both 'category' and 'categories' field names
|
||||||
|
const category = data.category || (Array.isArray(data.categories) ? data.categories[0] : 'ทั่วไป');
|
||||||
|
// Support both 'image' and 'featuredImage' field names
|
||||||
|
const image = data.image || data.featuredImage || '/images/2021/03/ppr-pipe_000C.jpg';
|
||||||
|
|
||||||
return {
|
return {
|
||||||
slug,
|
slug,
|
||||||
title: data.title || 'ไม่มีชื่อ',
|
title: data.title || 'ไม่มีชื่อ',
|
||||||
excerpt: data.excerpt || '',
|
excerpt: data.excerpt || '',
|
||||||
date: data.date || new Date().toISOString(),
|
date: data.date || new Date().toISOString(),
|
||||||
author: data.author || 'ดีลพลัสเทค',
|
author: data.author || 'ดีลพลัสเทค',
|
||||||
category: data.category || 'ทั่วไป',
|
category,
|
||||||
image: data.image || '/images/2021/03/ppr-pipe_000C.jpg',
|
image,
|
||||||
content: contentHtml,
|
content: contentHtml,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function generateMetadata({ params }: Props) {
|
export async function generateMetadata({ params }: Props) {
|
||||||
const post = await getPost(params.slug);
|
const { slug } = await params;
|
||||||
|
const decodedSlug = decodeURIComponent(slug);
|
||||||
|
const post = await getPost(decodedSlug);
|
||||||
if (!post) return { title: 'ไม่พบบทความ' };
|
if (!post) return { title: 'ไม่พบบทความ' };
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -59,7 +67,9 @@ export async function generateStaticParams() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default async function BlogPostPage({ params }: Props) {
|
export default async function BlogPostPage({ params }: Props) {
|
||||||
const post = await getPost(params.slug);
|
const { slug } = await params;
|
||||||
|
const decodedSlug = decodeURIComponent(slug);
|
||||||
|
const post = await getPost(decodedSlug);
|
||||||
|
|
||||||
if (!post) {
|
if (!post) {
|
||||||
notFound();
|
notFound();
|
||||||
|
|||||||
@@ -18,14 +18,19 @@ function getBlogPosts() {
|
|||||||
const fileContent = fs.readFileSync(filePath, 'utf-8');
|
const fileContent = fs.readFileSync(filePath, 'utf-8');
|
||||||
const { data } = matter(fileContent);
|
const { data } = matter(fileContent);
|
||||||
|
|
||||||
|
// Support both 'category' and 'categories' field names
|
||||||
|
const category = data.category || (Array.isArray(data.categories) ? data.categories[0] : 'ทั่วไป');
|
||||||
|
// Support both 'image' and 'featuredImage' field names
|
||||||
|
const image = data.image || data.featuredImage || '/images/2021/03/ppr-pipe_000C.jpg';
|
||||||
|
|
||||||
return {
|
return {
|
||||||
slug: filename.replace('.md', ''),
|
slug: filename.replace('.md', ''),
|
||||||
title: data.title || 'ไม่มีชื่อ',
|
title: data.title || 'ไม่มีชื่อ',
|
||||||
excerpt: data.excerpt || '',
|
excerpt: data.excerpt || '',
|
||||||
date: data.date || new Date().toISOString(),
|
date: data.date || new Date().toISOString(),
|
||||||
author: data.author || 'ดีลพลัสเทค',
|
author: data.author || 'ดีลพลัสเทค',
|
||||||
category: data.category || 'ทั่วไป',
|
category,
|
||||||
image: data.image || '/images/2021/03/ppr-pipe_000C.jpg',
|
image,
|
||||||
};
|
};
|
||||||
}).sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime());
|
}).sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,160 +19,87 @@ export default function ContactPage() {
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-12">
|
<div className="max-w-2xl mx-auto">
|
||||||
{/* Contact Info */}
|
{/* Contact Info */}
|
||||||
<div>
|
<div className="bg-secondary-800 rounded-2xl p-8 mb-8">
|
||||||
<div className="bg-secondary-800 rounded-2xl p-8 mb-8">
|
<h2 className="text-2xl font-bold text-white mb-6">ข้อมูลติดต่อ</h2>
|
||||||
<h2 className="text-2xl font-bold text-white mb-6">ข้อมูลติดต่อ</h2>
|
|
||||||
|
|
||||||
<div className="space-y-6">
|
<div className="space-y-6">
|
||||||
<div className="flex items-start gap-4">
|
<div className="flex items-start gap-4">
|
||||||
<div className="w-12 h-12 bg-primary-600 rounded-lg flex items-center justify-center flex-shrink-0">
|
<div className="w-12 h-12 bg-primary-600 rounded-lg flex items-center justify-center flex-shrink-0">
|
||||||
<svg className="w-6 h-6 text-white" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
<svg className="w-6 h-6 text-white" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M17.657 16.657L13.414 20.9a1.998 1.998 0 01-2.827 0l-4.244-4.243a8 8 0 1111.314 0z" />
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M17.657 16.657L13.414 20.9a1.998 1.998 0 01-2.827 0l-4.244-4.243a8 8 0 1111.314 0z" />
|
||||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 11a3 3 0 11-6 0 3 3 0 016 0z" />
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 11a3 3 0 11-6 0 3 3 0 016 0z" />
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<h3 className="font-bold text-white">ที่อยู่</h3>
|
|
||||||
<p className="text-secondary-300">{siteConfig.address}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
<div className="flex items-start gap-4">
|
<h3 className="font-bold text-white">ที่อยู่</h3>
|
||||||
<div className="w-12 h-12 bg-primary-600 rounded-lg flex items-center justify-center flex-shrink-0">
|
<p className="text-secondary-300">{siteConfig.address}</p>
|
||||||
<svg className="w-6 h-6 text-white" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
||||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M3 5a2 2 0 012-2h3.28a1 1 0 01.948.684l1.498 4.493a1 1 0 01-.502 1.21l-2.257 1.13a11.042 11.042 0 005.516 5.516l1.13-2.257a1 1 0 011.21-.502l4.493 1.498a1 1 0 01.684.949V19a2 2 0 01-2 2h-1C9.716 21 3 14.284 3 6V5z" />
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<h3 className="font-bold text-white">โทรศัพท์</h3>
|
|
||||||
<a href={`tel:${siteConfig.phone}`} className="text-primary-400 hover:text-primary-300">
|
|
||||||
{siteConfig.phone}
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className="flex items-start gap-4">
|
<div className="flex items-start gap-4">
|
||||||
<div className="w-12 h-12 bg-primary-600 rounded-lg flex items-center justify-center flex-shrink-0">
|
<div className="w-12 h-12 bg-primary-600 rounded-lg flex items-center justify-center flex-shrink-0">
|
||||||
<svg className="w-6 h-6 text-white" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
<svg className="w-6 h-6 text-white" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" />
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M3 5a2 2 0 012-2h3.28a1 1 0 01.948.684l1.498 4.493a1 1 0 01-.502 1.21l-2.257 1.13a11.042 11.042 0 005.516 5.516l1.13-2.257a1 1 0 011.21-.502l4.493 1.498a1 1 0 01.684.949V19a2 2 0 01-2 2h-1C9.716 21 3 14.284 3 6V5z" />
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<h3 className="font-bold text-white">อีเมล</h3>
|
|
||||||
<a href={`mailto:${siteConfig.email}`} className="text-primary-400 hover:text-primary-300">
|
|
||||||
{siteConfig.email}
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
<h3 className="font-bold text-white">โทรศัพท์</h3>
|
||||||
|
<a href={`tel:${siteConfig.phone}`} className="text-primary-400 hover:text-primary-300">
|
||||||
|
{siteConfig.phone}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className="flex items-start gap-4">
|
<div className="flex items-start gap-4">
|
||||||
<div className="w-12 h-12 bg-[#00B900] rounded-lg flex items-center justify-center flex-shrink-0">
|
<div className="w-12 h-12 bg-primary-600 rounded-lg flex items-center justify-center flex-shrink-0">
|
||||||
<svg className="w-6 h-6 text-white" viewBox="0 0 24 24" fill="currentColor">
|
<svg className="w-6 h-6 text-white" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||||
<path d="M19.365 9.863c.349 0 .63.285.63.631 0 .345-.281.63-.63.63H17.61v1.125h1.755c.349 0 .63.283.63.63 0 .344-.281.629-.63.629h-2.386c-.345 0-.627-.285-.627-.629V8.108c0-.345.282-.63.63-.63h2.386c.346 0 .627.285.627.63 0 .349-.281.63-.63.63H17.61v1.125h1.755zm-3.855 3.016c0 .27-.174.51-.432.596-.064.021-.133.031-.199.031-.211 0-.391-.09-.51-.25l-2.443-3.317v2.94c0 .344-.279.629-.631.629-.346 0-.626-.285-.626-.629V8.108c0-.27.173-.51.43-.595.06-.023.136-.033.194-.033.195 0 .375.104.495.254l2.462 3.33V8.108c0-.345.282-.63.63-.63.345 0 .63.285.63.63v4.771zm-5.741 0c0 .344-.282.629-.631.629-.345 0-.627-.285-.627-.629V8.108c0-.345.282-.63.63-.63.346 0 .628.285.628.63v4.771zm-2.466.629H4.917c-.345 0-.63-.285-.63-.629V8.108c0-.345.285-.63.63-.63.348 0 .63.285.63.63v4.141h1.756c.348 0 .629.283.629.63 0 .344-.282.629-.629.629M24 10.314C24 4.943 18.615.572 12 .572S0 4.943 0 10.314c0 4.811 4.27 8.842 10.035 9.608.391.082.923.258 1.058.59.12.301.079.766.038 1.08l-.164 1.02c-.045.301-.24 1.186 1.049.645 1.291-.539 6.916-4.078 9.436-6.975C23.176 14.393 24 12.458 24 10.314"/>
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" />
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h3 className="font-bold text-white">LINE Official</h3>
|
<h3 className="font-bold text-white">อีเมล</h3>
|
||||||
<a
|
<a href={`mailto:${siteConfig.email}`} className="text-primary-400 hover:text-primary-300">
|
||||||
href={`https://line.me/ti/p/${siteConfig.lineId}`}
|
{siteConfig.email}
|
||||||
target="_blank"
|
</a>
|
||||||
rel="noopener noreferrer"
|
</div>
|
||||||
className="text-primary-400 hover:text-primary-300"
|
</div>
|
||||||
>
|
|
||||||
{siteConfig.lineId}
|
<div className="flex items-start gap-4">
|
||||||
</a>
|
<div className="w-12 h-12 bg-[#00B900] rounded-lg flex items-center justify-center flex-shrink-0">
|
||||||
</div>
|
<svg className="w-6 h-6 text-white" viewBox="0 0 24 24" fill="currentColor">
|
||||||
|
<path d="M19.365 9.863c.349 0 .63.285.63.631 0 .345-.281.63-.63.63H17.61v1.125h1.755c.349 0 .63.283.63.63 0 .344-.281.629-.63.629h-2.386c-.345 0-.627-.285-.627-.629V8.108c0-.345.282-.63.63-.63h2.386c.346 0 .627.285.627.63 0 .349-.281.63-.63.63H17.61v1.125h1.755zm-3.855 3.016c0 .27-.174.51-.432.596-.064.021-.133.031-.199.031-.211 0-.391-.09-.51-.25l-2.443-3.317v2.94c0 .344-.279.629-.631.629-.346 0-.626-.285-.626-.629V8.108c0-.27.173-.51.43-.595.06-.023.136-.033.194-.033.195 0 .375.104.495.254l2.462 3.33V8.108c0-.345.282-.63.63-.63.345 0 .63.285.63.63v4.771zm-5.741 0c0 .344-.282.629-.631.629-.345 0-.627-.285-.627-.629V8.108c0-.345.282-.63.63-.63.346 0 .628.285.628.63v4.771zm-2.466.629H4.917c-.345 0-.63-.285-.63-.629V8.108c0-.345.285-.63.63-.63.348 0 .63.285.63.63v4.141h1.756c.348 0 .629.283.629.63 0 .344-.282.629-.629.629M24 10.314C24 4.943 18.615.572 12 .572S0 4.943 0 10.314c0 4.811 4.27 8.842 10.035 9.608.391.082.923.258 1.058.59.12.301.079.766.038 1.08l-.164 1.02c-.045.301-.24 1.186 1.049.645 1.291-.539 6.916-4.078 9.436-6.975C23.176 14.393 24 12.458 24 10.314"/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h3 className="font-bold text-white">LINE Official</h3>
|
||||||
|
<a
|
||||||
|
href={`https://line.me/ti/p/${siteConfig.lineId}`}
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
className="text-primary-400 hover:text-primary-300"
|
||||||
|
>
|
||||||
|
{siteConfig.lineId}
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Business Hours */}
|
|
||||||
<div className="bg-primary-600 rounded-2xl p-8">
|
|
||||||
<h2 className="text-2xl font-bold text-white mb-6">เวลาทำการ</h2>
|
|
||||||
<ul className="space-y-3">
|
|
||||||
{workHours.map((item) => (
|
|
||||||
<li key={item.day} className="flex justify-between">
|
|
||||||
<span className="text-primary-100">{item.day}</span>
|
|
||||||
<span className={`font-semibold ${item.isClosed ? 'text-red-200' : 'text-white'}`}>
|
|
||||||
{item.hours}
|
|
||||||
</span>
|
|
||||||
</li>
|
|
||||||
))}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Contact Form */}
|
{/* Business Hours */}
|
||||||
<div>
|
<div className="bg-primary-600 rounded-2xl p-8">
|
||||||
<div className="bg-white rounded-2xl shadow-card p-8">
|
<h2 className="text-2xl font-bold text-white mb-6">เวลาทำการ</h2>
|
||||||
<h2 className="text-2xl font-bold text-secondary-900 mb-6">ส่งข้อความถึงเรา</h2>
|
<ul className="space-y-3">
|
||||||
|
{workHours.map((item) => (
|
||||||
<form className="space-y-6">
|
<li key={item.day} className="flex justify-between">
|
||||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
<span className="text-primary-100">{item.day}</span>
|
||||||
<div>
|
<span className={`font-semibold ${item.isClosed ? 'text-red-200' : 'text-white'}`}>
|
||||||
<label className="block text-sm font-medium text-secondary-700 mb-2">
|
{item.hours}
|
||||||
ชื่อ-นามสกุล *
|
</span>
|
||||||
</label>
|
</li>
|
||||||
<input
|
))}
|
||||||
type="text"
|
</ul>
|
||||||
className="w-full px-4 py-3 rounded-lg border border-secondary-200 focus:border-primary-500 focus:ring-2 focus:ring-primary-500/20 outline-none transition-colors"
|
|
||||||
placeholder="ชื่อของคุณ"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<label className="block text-sm font-medium text-secondary-700 mb-2">
|
|
||||||
เบอร์โทรศัพท์ *
|
|
||||||
</label>
|
|
||||||
<input
|
|
||||||
type="tel"
|
|
||||||
className="w-full px-4 py-3 rounded-lg border border-secondary-200 focus:border-primary-500 focus:ring-2 focus:ring-primary-500/20 outline-none transition-colors"
|
|
||||||
placeholder="08x-xxx-xxxx"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<label className="block text-sm font-medium text-secondary-700 mb-2">
|
|
||||||
อีเมล
|
|
||||||
</label>
|
|
||||||
<input
|
|
||||||
type="email"
|
|
||||||
className="w-full px-4 py-3 rounded-lg border border-secondary-200 focus:border-primary-500 focus:ring-2 focus:ring-primary-500/20 outline-none transition-colors"
|
|
||||||
placeholder="email@example.com"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<label className="block text-sm font-medium text-secondary-700 mb-2">
|
|
||||||
หัวข้อ *
|
|
||||||
</label>
|
|
||||||
<select className="w-full px-4 py-3 rounded-lg border border-secondary-200 focus:border-primary-500 focus:ring-2 focus:ring-primary-500/20 outline-none transition-colors">
|
|
||||||
<option value="">เลือกหัวข้อ</option>
|
|
||||||
<option value="quote">ขอใบเสนอราคา</option>
|
|
||||||
<option value="product">สอบถามสินค้า</option>
|
|
||||||
<option value="service">สอบถามบริการ</option>
|
|
||||||
<option value="other">อื่นๆ</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<label className="block text-sm font-medium text-secondary-700 mb-2">
|
|
||||||
ข้อความ *
|
|
||||||
</label>
|
|
||||||
<textarea
|
|
||||||
rows={5}
|
|
||||||
className="w-full px-4 py-3 rounded-lg border border-secondary-200 focus:border-primary-500 focus:ring-2 focus:ring-primary-500/20 outline-none transition-colors resize-none"
|
|
||||||
placeholder="รายละเอียดที่ต้องการสอบถาม..."
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<button type="submit" className="btn-primary w-full">
|
|
||||||
ส่งข้อความ
|
|
||||||
</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -7,34 +7,79 @@ export const metadata = {
|
|||||||
|
|
||||||
const portfolioItems = [
|
const portfolioItems = [
|
||||||
{
|
{
|
||||||
title: 'โครงการอาคารสำนักงาน',
|
title: 'Cyber World',
|
||||||
category: 'อาคารพาณิชย์',
|
category: 'อาคารพาณิชย์',
|
||||||
image: '/images/2021/03/hdpe-pipe_000C.jpg',
|
image: '/images/2021/02/IMG_3089.jpg',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'โครงการโรงงานอุตสาหกรรม',
|
title: 'Toyox',
|
||||||
category: 'อุตสาหกรรม',
|
category: 'อุตสาหกรรม',
|
||||||
image: '/images/2021/03/ppr-pipe_000C.jpg',
|
image: '/images/2021/02/IMG_2226.jpg',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'โครงการบ้านพักอาศัย',
|
title: 'PPR PIPE',
|
||||||
category: 'ที่อยู่อาศัย',
|
category: 'ท่อ PPR',
|
||||||
image: '/images/2021/03/pvc-pipe_000C.jpg',
|
image: '/images/2021/02/Image1.jpg',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'โครงการระบบดับเพลิง',
|
title: 'โรงงานเอธานอล',
|
||||||
category: 'ระบบดับเพลิง',
|
category: 'อุตสาหกรรม',
|
||||||
image: '/images/2021/03/realflex_000C.jpg',
|
image: '/images/2021/02/ลพบุรี5.jpg',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'โครงการระบบปรับอากาศ',
|
title: 'บจก.หยั่น หว่อ หยุ่น',
|
||||||
category: 'HVAC',
|
category: 'อุตสาหกรรม',
|
||||||
image: '/images/2021/03/grilles_000C.jpg',
|
image: '/images/2021/02/สมุทรสาคร2.jpg',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'โครงการระบบประปา',
|
title: 'ซีคอนบางแค',
|
||||||
category: 'ระบบประปา',
|
category: 'อาคารพาณิชย์',
|
||||||
image: '/images/2021/03/upvc-pipe_000C.jpg',
|
image: '/images/2021/02/บางแค1.jpg',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'ซีพีแรม ลาดกระบัง',
|
||||||
|
category: 'อาคารพาณิชย์',
|
||||||
|
image: '/images/2021/02/ลาดกระบัง1.jpg',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'ซีพีแรม (บ่อเงิน)',
|
||||||
|
category: 'อาคารพาณิชย์',
|
||||||
|
image: '/images/2021/02/บ่อเงิน3.jpg',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'บริษัท บีกริม',
|
||||||
|
category: 'อุตสาหกรรม',
|
||||||
|
image: '/images/2021/02/บีกริม-จำกัด-e1503304339753.jpg',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'เอฟแอนด์เอฟ ฟูด',
|
||||||
|
category: 'อาหาร',
|
||||||
|
image: '/images/2021/02/เอฟแอนดืเอฟ2-horz.jpg',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Eminent Air Factory',
|
||||||
|
category: 'อุตสาหกรรม',
|
||||||
|
image: '/images/2021/02/บางพลี1-horz.jpg',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'ไทยน้ำทิพย์',
|
||||||
|
category: 'อุตสาหกรรม',
|
||||||
|
image: '/images/2021/02/ไทยน้ำทิพย์1-horz.jpg',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Essilor Factory',
|
||||||
|
category: 'อุตสาหกรรม',
|
||||||
|
image: '/images/2021/02/Essilor1-horz.jpg',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Dog Food Factory',
|
||||||
|
category: 'อาหาร',
|
||||||
|
image: '/images/2021/02/บ.เอเชี่ยน1.jpg',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'โครงการประชารัฐ',
|
||||||
|
category: 'ภาครัฐ',
|
||||||
|
image: '/images/2021/02/ประชารัฐ1-e1503323597848.jpg',
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -55,21 +100,24 @@ export default function PortfolioPage() {
|
|||||||
{/* Portfolio Grid */}
|
{/* Portfolio Grid */}
|
||||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||||
{portfolioItems.map((item, index) => (
|
{portfolioItems.map((item, index) => (
|
||||||
<div key={index} className="card group cursor-pointer">
|
<div key={index} className="card group cursor-pointer overflow-hidden">
|
||||||
<div className="relative aspect-video bg-secondary-100">
|
<div className="relative aspect-video bg-secondary-100 overflow-hidden">
|
||||||
<Image
|
<Image
|
||||||
src={item.image}
|
src={item.image}
|
||||||
alt={item.title}
|
alt={item.title}
|
||||||
fill
|
fill
|
||||||
className="object-cover group-hover:scale-105 transition-transform duration-300"
|
className="object-cover group-hover:scale-105 transition-transform duration-300"
|
||||||
/>
|
/>
|
||||||
<div className="absolute inset-0 bg-gradient-to-t from-secondary-900/80 to-transparent opacity-0 group-hover:opacity-100 transition-opacity" />
|
{/* Hover Overlay */}
|
||||||
<div className="absolute bottom-0 left-0 right-0 p-4 translate-y-full group-hover:translate-y-0 transition-transform">
|
<div className="absolute inset-0 bg-gradient-to-t from-secondary-900/80 to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-300" />
|
||||||
|
{/* Hover Text - hidden by default, slides up on hover */}
|
||||||
|
<div className="absolute bottom-0 left-0 right-0 p-4 translate-y-full group-hover:translate-y-0 transition-transform duration-300">
|
||||||
<span className="text-primary-400 text-sm">{item.category}</span>
|
<span className="text-primary-400 text-sm">{item.category}</span>
|
||||||
<h3 className="text-white font-bold">{item.title}</h3>
|
<h3 className="text-white font-bold">{item.title}</h3>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="p-4 group-hover:hidden">
|
{/* Static Info - only visible when NOT hovering */}
|
||||||
|
<div className="p-4 bg-white group-hover:hidden">
|
||||||
<span className="text-xs text-primary-600 font-semibold">{item.category}</span>
|
<span className="text-xs text-primary-600 font-semibold">{item.category}</span>
|
||||||
<h3 className="text-lg font-bold text-secondary-900 mt-1">{item.title}</h3>
|
<h3 className="text-lg font-bold text-secondary-900 mt-1">{item.title}</h3>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import { cn } from '@/lib/utils';
|
|||||||
|
|
||||||
export default function Header() {
|
export default function Header() {
|
||||||
const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
|
const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
|
||||||
const [activeDropdown, setActiveDropdown] = useState<string | null>(null);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<header className="fixed top-0 left-0 right-0 z-50 bg-white shadow-md">
|
<header className="fixed top-0 left-0 right-0 z-50 bg-white shadow-md">
|
||||||
@@ -60,9 +59,7 @@ export default function Header() {
|
|||||||
{mainNavigation.map((item) => (
|
{mainNavigation.map((item) => (
|
||||||
<div
|
<div
|
||||||
key={item.href}
|
key={item.href}
|
||||||
className="relative"
|
className="relative group"
|
||||||
onMouseEnter={() => item.children && setActiveDropdown(item.href)}
|
|
||||||
onMouseLeave={() => setActiveDropdown(null)}
|
|
||||||
>
|
>
|
||||||
<Link
|
<Link
|
||||||
href={item.href}
|
href={item.href}
|
||||||
@@ -79,33 +76,39 @@ export default function Header() {
|
|||||||
)}
|
)}
|
||||||
</Link>
|
</Link>
|
||||||
|
|
||||||
{/* Dropdown */}
|
{/* Dropdown - CSS hover with invisible bridge */}
|
||||||
{item.children && activeDropdown === item.href && (
|
{item.children && (
|
||||||
<div className="absolute top-full left-1/2 -translate-x-1/2 min-w-[600px] bg-white shadow-xl rounded-lg py-4 mt-2 border border-secondary-100">
|
<div className="absolute top-full left-0 pt-2 opacity-0 invisible group-hover:opacity-100 group-hover:visible transition-all duration-200 z-50">
|
||||||
<div className="grid grid-cols-2 gap-1 px-4">
|
{/* Invisible bridge to prevent gap */}
|
||||||
{item.children.map((child) => (
|
<div className="absolute -top-2 left-0 right-0 h-2" />
|
||||||
<div key={child.href} className="relative group">
|
<div className="min-w-[600px] bg-white shadow-xl rounded-lg py-4 border border-secondary-100">
|
||||||
<Link
|
<div className="grid grid-cols-2 gap-1 px-4">
|
||||||
href={child.href}
|
{item.children.map((child) => (
|
||||||
className="block px-3 py-2 text-secondary-700 hover:bg-primary-50 hover:text-primary-700 transition-colors rounded font-medium"
|
<div key={child.href} className="relative group/sub">
|
||||||
>
|
<Link
|
||||||
{child.label}
|
href={child.href}
|
||||||
</Link>
|
className="block px-3 py-2 text-secondary-700 hover:bg-primary-50 hover:text-primary-700 transition-colors rounded font-medium"
|
||||||
{child.children && (
|
>
|
||||||
<div className="hidden group-hover:block absolute left-full top-0 ml-2 w-56 bg-white shadow-xl rounded-lg py-2 border border-secondary-100 max-h-96 overflow-y-auto">
|
{child.label}
|
||||||
{child.children.map((subChild) => (
|
</Link>
|
||||||
<Link
|
{child.children && (
|
||||||
key={subChild.href}
|
<div className="hidden group-hover/sub:block absolute left-full top-0 w-56 !bg-white shadow-xl rounded-lg py-2 border border-secondary-100 max-h-96 overflow-y-auto z-50">
|
||||||
href={subChild.href}
|
{/* Invisible bridge to prevent gap */}
|
||||||
className="block px-4 py-2 text-secondary-600 hover:bg-primary-50 hover:text-primary-700 text-sm"
|
<div className="absolute -top-2 -bottom-2 -left-2 w-2" />
|
||||||
>
|
{child.children.map((subChild) => (
|
||||||
{subChild.label}
|
<Link
|
||||||
</Link>
|
key={subChild.href}
|
||||||
))}
|
href={subChild.href}
|
||||||
</div>
|
className="block px-4 py-2 text-secondary-600 hover:bg-primary-50 hover:text-primary-700 text-sm"
|
||||||
)}
|
>
|
||||||
</div>
|
{subChild.label}
|
||||||
))}
|
</Link>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|||||||