feat: อัพเดทเว็บไซต์ใหม่ - 5 บริการหลัก + 10 บทความ SEO
- เพิ่มบริการใหม่ 5 ด้าน: AI-Enhanced Website, Marketing Automation, SEO + AI Content, Tech Consult, AI Automation - ลบบริการเดิมที่ไม่ใช้: AI Strategy, AI Training, AI Analytics - สร้าง blog ใหม่ 10 บทความ พร้อม SEO/AEO optimization - เพิ่ม blog listing page และ blog detail template - อัพเดท layout, navigation, footer ให้สอดคล้องกับบริการใหม่ - เพิ่ม LINE contact icon (พร้อม placeholder link) - แก้ CSS bugs: text contrast บน gradient backgrounds - ปรับปรุง meta tags และ Schema.org structured data - ย้ายจาก /category/seo เป็น /blog Services: - /web-development - /marketing-automation - /seo-content-system - /tech-consult - /ai-automation Blog: /blog (10 articles)
This commit is contained in:
268
src/pages/blog/[slug].astro
Normal file
268
src/pages/blog/[slug].astro
Normal file
@@ -0,0 +1,268 @@
|
||||
---
|
||||
import Layout from '../../layouts/Layout.astro';
|
||||
import { getCollection } from 'astro:content';
|
||||
|
||||
export async function getStaticPaths() {
|
||||
const posts = await getCollection('blog');
|
||||
return posts.map(post => ({
|
||||
params: { slug: post.slug },
|
||||
props: { post },
|
||||
}));
|
||||
}
|
||||
|
||||
const { post } = Astro.props;
|
||||
const { Content } = await post.render();
|
||||
|
||||
const formatDate = (date: Date) => {
|
||||
return date.toLocaleDateString('th-TH', {
|
||||
year: 'numeric',
|
||||
month: 'long',
|
||||
day: 'numeric'
|
||||
});
|
||||
};
|
||||
|
||||
// Schema.org Article structured data
|
||||
const schemaData = {
|
||||
"@context": "https://schema.org",
|
||||
"@type": "Article",
|
||||
"headline": post.data.title,
|
||||
"description": post.data.description,
|
||||
"image": post.data.image || "/branding/logo-long.png",
|
||||
"datePublished": post.data.pubDate.toISOString(),
|
||||
"dateModified": post.data.pubDate.toISOString(),
|
||||
"author": {
|
||||
"@type": "Person",
|
||||
"name": post.data.author
|
||||
},
|
||||
"publisher": {
|
||||
"@type": "Organization",
|
||||
"name": "MoreMiniMore",
|
||||
"logo": {
|
||||
"@type": "ImageObject",
|
||||
"url": "/branding/logo-long.png"
|
||||
}
|
||||
}
|
||||
};
|
||||
---
|
||||
|
||||
<Layout
|
||||
title={`${post.data.title} | MoreMiniMore Blog`}
|
||||
description={post.data.description}
|
||||
>
|
||||
<!-- Schema.org JSON-LD -->
|
||||
<script type="application/ld+json" set:html={JSON.stringify(schemaData)} />
|
||||
|
||||
<!-- Article Header -->
|
||||
<section class="py-12 bg-gray-light">
|
||||
<div class="container mx-auto px-4 max-w-4xl">
|
||||
<nav class="text-sm mb-6">
|
||||
<a href="/blog" class="text-accent-blue hover:underline">← กลับไปหน้าบล็อก</a>
|
||||
</nav>
|
||||
|
||||
<div class="flex items-center gap-2 mb-4">
|
||||
<span class="bg-primary text-white px-3 py-1 rounded-full text-sm font-medium">
|
||||
{post.data.category}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<h1 class="text-3xl md:text-4xl lg:text-5xl font-bold mb-6 text-secondary leading-tight">
|
||||
{post.data.title}
|
||||
</h1>
|
||||
|
||||
<div class="flex flex-wrap items-center gap-4 text-gray-600">
|
||||
<span class="flex items-center gap-2">
|
||||
<span class="text-xl">✍️</span>
|
||||
{post.data.author}
|
||||
</span>
|
||||
<span class="flex items-center gap-2">
|
||||
<span class="text-xl">📅</span>
|
||||
{formatDate(post.data.pubDate)}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Article Content -->
|
||||
<section class="py-12 bg-white">
|
||||
<div class="container mx-auto px-4 max-w-4xl">
|
||||
<article class="prose prose-lg max-w-none">
|
||||
<Content />
|
||||
</article>
|
||||
|
||||
<!-- Tags -->
|
||||
<div class="mt-12 pt-8 border-t">
|
||||
<div class="flex flex-wrap gap-2">
|
||||
{post.data.tags.map(tag => (
|
||||
<a href={`/blog?tag=${tag}`} class="px-4 py-2 bg-gray-100 rounded-full text-gray-700 hover:bg-primary hover:text-white transition">
|
||||
#{tag}
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Share Section -->
|
||||
<section class="py-8 bg-gray-light">
|
||||
<div class="container mx-auto px-4 max-w-4xl text-center">
|
||||
<h3 class="text-xl font-bold mb-4">แชร์บทความนี้</h3>
|
||||
<div class="flex justify-center gap-4">
|
||||
<a
|
||||
href={`https://www.facebook.com/sharer/sharer.php?u=${Astro.url}`}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="px-6 py-3 bg-blue-600 text-white rounded-full hover:bg-blue-700 transition inline-flex items-center gap-2"
|
||||
>
|
||||
📘 Facebook
|
||||
</a>
|
||||
<a
|
||||
href={`https://twitter.com/intent/tweet?url=${Astro.url}&text=${post.data.title}`}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="px-6 py-3 bg-black text-white rounded-full hover:bg-gray-800 transition inline-flex items-center gap-2"
|
||||
>
|
||||
🐦 Twitter
|
||||
</a>
|
||||
<a
|
||||
href={`https://line.me/R/msg/text/?${post.data.title}%20${Astro.url}`}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="px-6 py-3 bg-green-500 text-white rounded-full hover:bg-green-600 transition inline-flex items-center gap-2"
|
||||
>
|
||||
💬 LINE
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Related Articles -->
|
||||
<section class="py-12 bg-white">
|
||||
<div class="container mx-auto px-4 max-w-6xl">
|
||||
<h2 class="text-2xl font-bold mb-8 text-center">บทความที่เกี่ยวข้อง</h2>
|
||||
<div class="grid md:grid-cols-3 gap-8">
|
||||
<!-- Related articles would be dynamically loaded -->
|
||||
<div class="text-center text-gray-500">
|
||||
<p>กำลังอัปเดตบทความที่เกี่ยวข้อง...</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- CTA Section -->
|
||||
<section class="py-16 gradient-ai text-white">
|
||||
<div class="container mx-auto px-4 text-center">
|
||||
<h2 class="text-3xl md:text-4xl font-bold mb-6">
|
||||
ต้องการคำปรึกษาเพิ่มเติม?
|
||||
</h2>
|
||||
<p class="text-xl mb-8 max-w-2xl mx-auto">
|
||||
ทีมผู้เชี่ยวชาญของเราพร้อมให้คำปรึกษาฟรี
|
||||
</p>
|
||||
<div class="flex flex-col sm:flex-row gap-4 justify-center">
|
||||
<a href="/contact-us" class="bg-white text-primary px-8 py-4 rounded-full font-bold text-lg hover:bg-gray-100 transition shadow-lg inline-flex items-center justify-center gap-2">
|
||||
📞 ติดต่อเรา
|
||||
</a>
|
||||
<a href="/ai-strategy-consult" class="bg-transparent border-2 border-white text-white px-8 py-4 rounded-full font-bold text-lg hover:bg-white hover:text-primary transition inline-flex items-center justify-center gap-2">
|
||||
ปรึกษาผู้เชี่ยวชาญ
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</Layout>
|
||||
|
||||
<style is:global>
|
||||
.prose h1 {
|
||||
font-size: 2rem;
|
||||
font-weight: 700;
|
||||
margin-top: 2rem;
|
||||
margin-bottom: 1rem;
|
||||
color: #1a1a1a;
|
||||
}
|
||||
|
||||
.prose h2 {
|
||||
font-size: 1.5rem;
|
||||
font-weight: 700;
|
||||
margin-top: 2rem;
|
||||
margin-bottom: 1rem;
|
||||
color: #1a1a1a;
|
||||
}
|
||||
|
||||
.prose h3 {
|
||||
font-size: 1.25rem;
|
||||
font-weight: 600;
|
||||
margin-top: 1.5rem;
|
||||
margin-bottom: 0.75rem;
|
||||
color: #1a1a1a;
|
||||
}
|
||||
|
||||
.prose p {
|
||||
margin-bottom: 1.25rem;
|
||||
line-height: 1.8;
|
||||
color: #4a4a4a;
|
||||
}
|
||||
|
||||
.prose ul, .prose ol {
|
||||
margin-bottom: 1.25rem;
|
||||
padding-left: 1.5rem;
|
||||
}
|
||||
|
||||
.prose li {
|
||||
margin-bottom: 0.5rem;
|
||||
line-height: 1.7;
|
||||
}
|
||||
|
||||
.prose ul li {
|
||||
list-style-type: disc;
|
||||
}
|
||||
|
||||
.prose ol li {
|
||||
list-style-type: decimal;
|
||||
}
|
||||
|
||||
.prose strong {
|
||||
font-weight: 600;
|
||||
color: #1a1a1a;
|
||||
}
|
||||
|
||||
.prose a {
|
||||
color: #0066cc;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.prose a:hover {
|
||||
color: #0052a3;
|
||||
}
|
||||
|
||||
.prose blockquote {
|
||||
border-left: 4px solid #0066cc;
|
||||
padding-left: 1rem;
|
||||
margin: 1.5rem 0;
|
||||
font-style: italic;
|
||||
color: #666;
|
||||
background: #f9f9f9;
|
||||
padding: 1rem;
|
||||
border-radius: 0 8px 8px 0;
|
||||
}
|
||||
|
||||
.prose hr {
|
||||
margin: 2rem 0;
|
||||
border: none;
|
||||
border-top: 1px solid #e5e5e5;
|
||||
}
|
||||
|
||||
.prose table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin: 1.5rem 0;
|
||||
}
|
||||
|
||||
.prose th, .prose td {
|
||||
border: 1px solid #e5e5e5;
|
||||
padding: 0.75rem;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.prose th {
|
||||
background: #f5f5f5;
|
||||
font-weight: 600;
|
||||
}
|
||||
</style>
|
||||
259
src/pages/blog/index.astro
Normal file
259
src/pages/blog/index.astro
Normal file
@@ -0,0 +1,259 @@
|
||||
---
|
||||
import Layout from '../../layouts/Layout.astro';
|
||||
import { getCollection } from 'astro:content';
|
||||
|
||||
export async function getStaticPaths() {
|
||||
const posts = await getCollection('blog');
|
||||
return posts.map(post => ({
|
||||
params: { slug: post.slug },
|
||||
props: { post },
|
||||
}));
|
||||
}
|
||||
|
||||
const allPosts = await getCollection('blog');
|
||||
const sortedPosts = allPosts.sort((a, b) => b.data.pubDate.valueOf() - a.data.pubDate.valueOf());
|
||||
|
||||
const categories = [...new Set(allPosts.map(post => post.data.category))];
|
||||
const tags = [...new Set(allPosts.flatMap(post => post.data.tags))];
|
||||
|
||||
const formatDate = (date: Date) => {
|
||||
return date.toLocaleDateString('th-TH', {
|
||||
year: 'numeric',
|
||||
month: 'long',
|
||||
day: 'numeric'
|
||||
});
|
||||
};
|
||||
---
|
||||
|
||||
<Layout
|
||||
title="บล็อก | MoreMiniMore - ความรู้เกี่ยวกับ AI และการตลาดดิจิทัล"
|
||||
description="อ่านบทความและความรู้เกี่ยวกับ AI, Marketing Automation, SEO และ Digital Transformation สำหรับธุรกิจ SMEs ไทย"
|
||||
>
|
||||
<section class="py-16 bg-gray-light">
|
||||
<div class="container mx-auto px-4">
|
||||
<div class="max-w-4xl mx-auto text-center">
|
||||
<h1 class="text-4xl md:text-5xl font-bold mb-6 text-secondary">
|
||||
บล็อก & ความรู้
|
||||
</h1>
|
||||
<p class="text-xl text-gray-600 mb-8">
|
||||
ความรู้เกี่ยวกับ AI, การตลาดดิจิทัล และการเปลี่ยนแปลงทางธุรกิจสำหรับ SMEs ไทย
|
||||
</p>
|
||||
|
||||
<!-- Search Box -->
|
||||
<div class="max-w-2xl mx-auto">
|
||||
<div class="relative">
|
||||
<input
|
||||
type="text"
|
||||
id="blog-search"
|
||||
placeholder="ค้นหาบทความ..."
|
||||
class="w-full px-6 py-4 pr-12 rounded-full border-2 border-gray-200 focus:border-primary focus:outline-none text-lg"
|
||||
/>
|
||||
<button class="absolute right-4 top-1/2 -translate-y-1/2 text-gray-400 hover:text-primary transition">
|
||||
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Category Filter -->
|
||||
<section class="py-8 bg-white border-b">
|
||||
<div class="container mx-auto px-4">
|
||||
<div class="flex flex-wrap gap-3 justify-center" id="category-filters">
|
||||
<button
|
||||
class="category-btn active px-5 py-2 rounded-full bg-primary text-white font-medium transition hover:bg-primary/90"
|
||||
data-category="all"
|
||||
>
|
||||
ทั้งหมด
|
||||
</button>
|
||||
{categories.map(category => (
|
||||
<button
|
||||
class="category-btn px-5 py-2 rounded-full bg-gray-100 text-gray-700 font-medium transition hover:bg-primary hover:text-white"
|
||||
data-category={category}
|
||||
>
|
||||
{category}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Blog Grid -->
|
||||
<section class="py-16 bg-gray-light">
|
||||
<div class="container mx-auto px-4">
|
||||
<div class="grid md:grid-cols-2 lg:grid-cols-3 gap-8" id="blog-grid">
|
||||
{sortedPosts.map(post => (
|
||||
<article class="blog-card bg-white rounded-2xl overflow-hidden shadow-md card-hover" data-category={post.data.category} data-tags={JSON.stringify(post.data.tags)}>
|
||||
<div class="h-48 gradient-ai flex items-center justify-center">
|
||||
<div class="text-6xl">📝</div>
|
||||
</div>
|
||||
<div class="p-6">
|
||||
<div class="flex items-center gap-2 mb-3">
|
||||
<span class="text-sm text-accent-blue font-bold">{post.data.category}</span>
|
||||
<span class="text-gray-300">|</span>
|
||||
<span class="text-sm text-gray-500">{formatDate(post.data.pubDate)}</span>
|
||||
</div>
|
||||
<h2 class="text-xl font-bold mb-3 line-clamp-2 hover:text-accent-blue transition">
|
||||
<a href={`/blog/${post.slug}`}>{post.data.title}</a>
|
||||
</h2>
|
||||
<p class="text-gray-600 mb-4 line-clamp-3">
|
||||
{post.data.description}
|
||||
</p>
|
||||
<div class="flex flex-wrap gap-2 mb-4">
|
||||
{post.data.tags.slice(0, 3).map(tag => (
|
||||
<span class="text-xs bg-gray-100 px-2 py-1 rounded text-gray-600">#{tag}</span>
|
||||
))}
|
||||
</div>
|
||||
<a href={`/blog/${post.slug}`} class="text-accent-blue font-medium hover:underline inline-flex items-center gap-2">
|
||||
อ่านเพิ่มเติม →
|
||||
</a>
|
||||
</div>
|
||||
</article>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<!-- No Results Message -->
|
||||
<div id="no-results" class="hidden text-center py-16">
|
||||
<div class="text-6xl mb-4">🔍</div>
|
||||
<h3 class="text-2xl font-bold mb-2">ไม่พบบทความที่ค้นหา</h3>
|
||||
<p class="text-gray-600">ลองค้นหาด้วยคำอื่นหรือเลือกหมวดหมู่อื่น</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Tags Cloud -->
|
||||
<section class="py-12 bg-white">
|
||||
<div class="container mx-auto px-4 max-w-4xl">
|
||||
<h3 class="text-2xl font-bold mb-6 text-center">หัวข้อที่น่าสนใจ</h3>
|
||||
<div class="flex flex-wrap gap-3 justify-center">
|
||||
{tags.map(tag => (
|
||||
<a href={`/blog?tag=${tag}`} class="px-4 py-2 bg-gray-100 rounded-full text-gray-700 hover:bg-primary hover:text-white transition">
|
||||
#{tag}
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- CTA Section -->
|
||||
<section class="py-16 gradient-ai text-white">
|
||||
<div class="container mx-auto px-4 text-center">
|
||||
<h2 class="text-3xl md:text-4xl font-bold mb-6">
|
||||
พร้อมเริ่มต้น Digital Transformation แล้วหรือยัง?
|
||||
</h2>
|
||||
<p class="text-xl mb-8 max-w-2xl mx-auto">
|
||||
ปรึกษาผู้เชี่ยวชาญของเราฟรี เราพร้อมช่วยคุณวางกลยุทธ์ที่เหมาะกับธุรกิจ
|
||||
</p>
|
||||
<div class="flex flex-col sm:flex-row gap-4 justify-center">
|
||||
<a href="/contact-us" class="bg-white text-primary px-8 py-4 rounded-full font-bold text-lg hover:bg-gray-100 transition shadow-lg inline-flex items-center justify-center gap-2">
|
||||
📞 ติดต่อเรา
|
||||
</a>
|
||||
<a href="/ai-strategy-consult" class="bg-transparent border-2 border-white text-white px-8 py-4 rounded-full font-bold text-lg hover:bg-white hover:text-primary transition inline-flex items-center justify-center gap-2">
|
||||
ปรึกษาผู้เชี่ยวชาญ
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</Layout>
|
||||
|
||||
<script>
|
||||
// Category Filter
|
||||
const categoryBtns = document.querySelectorAll('.category-btn');
|
||||
const blogCards = document.querySelectorAll('.blog-card');
|
||||
const noResults = document.getElementById('no-results');
|
||||
const blogGrid = document.getElementById('blog-grid');
|
||||
|
||||
categoryBtns.forEach(btn => {
|
||||
btn.addEventListener('click', () => {
|
||||
// Update active state
|
||||
categoryBtns.forEach(b => {
|
||||
b.classList.remove('active', 'bg-primary', 'text-white');
|
||||
b.classList.add('bg-gray-100', 'text-gray-700');
|
||||
});
|
||||
btn.classList.add('active', 'bg-primary', 'text-white');
|
||||
btn.classList.remove('bg-gray-100', 'text-gray-700');
|
||||
|
||||
const category = btn.getAttribute('data-category');
|
||||
|
||||
// Filter cards
|
||||
let visibleCount = 0;
|
||||
blogCards.forEach(card => {
|
||||
const cardCategory = card.getAttribute('data-category');
|
||||
if (category === 'all' || cardCategory === category) {
|
||||
(card as HTMLElement).style.display = 'block';
|
||||
visibleCount++;
|
||||
} else {
|
||||
(card as HTMLElement).style.display = 'none';
|
||||
}
|
||||
});
|
||||
|
||||
// Show/hide no results message
|
||||
if (visibleCount === 0) {
|
||||
noResults?.classList.remove('hidden');
|
||||
blogGrid?.classList.add('hidden');
|
||||
} else {
|
||||
noResults?.classList.add('hidden');
|
||||
blogGrid?.classList.remove('hidden');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Search Functionality
|
||||
const searchInput = document.getElementById('blog-search');
|
||||
searchInput?.addEventListener('input', (e) => {
|
||||
const searchTerm = (e.target as HTMLInputElement).value.toLowerCase();
|
||||
|
||||
let visibleCount = 0;
|
||||
blogCards.forEach(card => {
|
||||
const title = card.querySelector('h2')?.textContent?.toLowerCase() || '';
|
||||
const description = card.querySelector('p')?.textContent?.toLowerCase() || '';
|
||||
const tags = card.getAttribute('data-tags')?.toLowerCase() || '';
|
||||
|
||||
if (title.includes(searchTerm) || description.includes(searchTerm) || tags.includes(searchTerm)) {
|
||||
(card as HTMLElement).style.display = 'block';
|
||||
visibleCount++;
|
||||
} else {
|
||||
(card as HTMLElement).style.display = 'none';
|
||||
}
|
||||
});
|
||||
|
||||
// Show/hide no results message
|
||||
if (visibleCount === 0) {
|
||||
noResults?.classList.remove('hidden');
|
||||
blogGrid?.classList.add('hidden');
|
||||
} else {
|
||||
noResults?.classList.add('hidden');
|
||||
blogGrid?.classList.remove('hidden');
|
||||
}
|
||||
});
|
||||
|
||||
// URL parameter for tag filter
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
const tagParam = urlParams.get('tag');
|
||||
if (tagParam) {
|
||||
const searchInput = document.getElementById('blog-search') as HTMLInputElement;
|
||||
if (searchInput) {
|
||||
searchInput.value = tagParam;
|
||||
searchInput.dispatchEvent(new Event('input'));
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.line-clamp-2 {
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.line-clamp-3 {
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 3;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user