Compare commits
61 Commits
494b50925e
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f114a34a62 | ||
|
|
689a8924e6 | ||
|
|
2a3062357f | ||
|
|
1d893e1bcb | ||
|
|
61c2bd6924 | ||
|
|
fdb03f6117 | ||
|
|
0f244424c0 | ||
|
|
f827afb33f | ||
|
|
e279119f97 | ||
|
|
ceffb2a3f3 | ||
|
|
73d820412a | ||
|
|
40382bbf55 | ||
|
|
8b04c739e1 | ||
|
|
caab40d9a4 | ||
|
|
96caca4af6 | ||
|
|
5393cf611c | ||
|
|
b8ac07996e | ||
|
|
caa412dbe2 | ||
|
|
8c2bf3d303 | ||
|
|
154e3f2d91 | ||
|
|
b586464b5c | ||
|
|
1f859921cb | ||
|
|
582998a340 | ||
|
|
9eea9cbe6d | ||
|
|
ed03060ff7 | ||
|
|
45f548421d | ||
|
|
b54657f58a | ||
|
|
c334b8b650 | ||
|
|
dcd1d73f56 | ||
|
|
84e245a7bb | ||
|
|
5f05489316 | ||
|
|
d3421f4003 | ||
|
|
58c27d3bb3 | ||
|
|
f86c9b24c4 | ||
|
|
5ab00efd15 | ||
|
|
a7a0135727 | ||
|
|
9fca75044d | ||
|
|
57eaa9da8b | ||
|
|
746d51569b | ||
|
|
a1b1b16288 | ||
|
|
0ff6ae9020 | ||
|
|
f47949c4b3 | ||
|
|
c92d446ff7 | ||
|
|
bd1c979f1a | ||
|
|
9e7d27c03c | ||
|
|
b49931a87a | ||
|
|
525dc358a3 | ||
|
|
43f609a794 | ||
|
|
b5be45bcd6 | ||
|
|
789473271e | ||
|
|
ca7f99ed41 | ||
|
|
3f1c0061c7 | ||
|
|
892c75b7a6 | ||
|
|
0f79808a43 | ||
|
|
6701c462ee | ||
|
|
5437a34124 | ||
|
|
0855e3d77b | ||
|
|
00b0de2d9a | ||
|
|
9fba7f2fd6 | ||
|
|
0faf75a9a2 | ||
|
|
b7787cc403 |
@@ -1,578 +0,0 @@
|
||||
{
|
||||
"version": "1",
|
||||
"collections": [
|
||||
{
|
||||
"slug": "pages",
|
||||
"label": "Pages",
|
||||
"fields": [
|
||||
{ "slug": "title", "type": "string", "label": "Title" },
|
||||
{ "slug": "subtitle", "type": "string", "label": "Subtitle" },
|
||||
{ "slug": "badge", "type": "string", "label": "Badge" },
|
||||
{ "slug": "hero_image", "type": "image", "label": "Hero Image" },
|
||||
{ "slug": "theme", "type": "select", "label": "Theme", "options": ["yellow", "accent"] },
|
||||
{ "slug": "show_cta", "type": "boolean", "label": "Show CTA" },
|
||||
{ "slug": "cta_text", "type": "string", "label": "CTA Text" },
|
||||
{ "slug": "cta_link", "type": "string", "label": "CTA Link" },
|
||||
{ "slug": "variant", "type": "select", "label": "Hero Variant", "options": ["split", "centered", "text_only", "floating_cards"] },
|
||||
{ "slug": "size", "type": "select", "label": "Hero Size", "options": ["full", "compact"] }
|
||||
]
|
||||
},
|
||||
{
|
||||
"slug": "services",
|
||||
"label": "Services",
|
||||
"fields": [
|
||||
{ "slug": "title", "type": "string", "label": "Title" },
|
||||
{ "slug": "subtitle", "type": "string", "label": "Subtitle" },
|
||||
{ "slug": "badge", "type": "string", "label": "Badge" },
|
||||
{ "slug": "hero_image", "type": "image", "label": "Hero Image" },
|
||||
{ "slug": "content", "type": "portableText", "label": "Content" },
|
||||
{
|
||||
"slug": "features",
|
||||
"type": "repeater",
|
||||
"label": "Features",
|
||||
"fields": [
|
||||
{ "slug": "icon", "type": "string", "label": "Icon" },
|
||||
{ "slug": "feature_title", "type": "string", "label": "Title" },
|
||||
{ "slug": "description", "type": "string", "label": "Description" }
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"slug": "portfolio",
|
||||
"label": "Portfolio",
|
||||
"fields": [
|
||||
{ "slug": "name", "type": "string", "label": "Name" },
|
||||
{ "slug": "url", "type": "url", "label": "URL" },
|
||||
{ "slug": "category", "type": "select", "label": "Category", "options": ["webdev", "ecommerce", "marketing"] },
|
||||
{ "slug": "category_label", "type": "string", "label": "Category Label" },
|
||||
{ "slug": "thumbnail", "type": "image", "label": "Thumbnail" },
|
||||
{ "slug": "description", "type": "text", "label": "Description" },
|
||||
{
|
||||
"slug": "services",
|
||||
"type": "repeater",
|
||||
"label": "Services",
|
||||
"fields": [
|
||||
{ "slug": "service_name", "type": "string", "label": "Name" }
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"slug": "blog",
|
||||
"label": "Blog",
|
||||
"fields": [
|
||||
{ "slug": "title", "type": "string", "label": "Title" },
|
||||
{ "slug": "excerpt", "type": "string", "label": "Excerpt" },
|
||||
{ "slug": "image", "type": "image", "label": "Image" },
|
||||
{ "slug": "date", "type": "datetime", "label": "Date" },
|
||||
{ "slug": "category", "type": "string", "label": "Category" },
|
||||
{ "slug": "content", "type": "portableText", "label": "Content" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"slug": "faq",
|
||||
"label": "FAQ",
|
||||
"fields": [
|
||||
{ "slug": "category", "type": "string", "label": "Category" },
|
||||
{ "slug": "question", "type": "string", "label": "Question" },
|
||||
{ "slug": "answer", "type": "text", "label": "Answer" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"slug": "settings",
|
||||
"label": "Site Settings",
|
||||
"fields": [
|
||||
{ "slug": "site_name", "type": "string", "label": "Site Name" },
|
||||
{ "slug": "email", "type": "string", "label": "Contact Email" },
|
||||
{ "slug": "phone", "type": "string", "label": "Contact Phone" },
|
||||
{ "slug": "address", "type": "text", "label": "Address" },
|
||||
{ "slug": "facebook", "type": "url", "label": "Facebook URL" },
|
||||
{ "slug": "line", "type": "url", "label": "LINE URL" },
|
||||
{ "slug": "linkedin", "type": "url", "label": "LinkedIn URL" }
|
||||
]
|
||||
}
|
||||
],
|
||||
"content": {
|
||||
"pages": [
|
||||
{
|
||||
"id": "page-home",
|
||||
"slug": "home",
|
||||
"data": {
|
||||
"title": "เปลี่ยนธุรกิจของคุณ ด้วย AI และเทคโนโลยีสมัยใหม่",
|
||||
"subtitle": "รับทำเว็บไซต์ SEO AI Chatbot สำหรับธุรกิจไทย<br>เพิ่มยอดขาย ลดต้นทุน ด้วยเทคโนโลยีล้ำสมัย",
|
||||
"badge": "ดิจิทัลเอเจนซี่ในประเทศไทย",
|
||||
"hero_image": "/images/hero/hero.jpg",
|
||||
"theme": "yellow",
|
||||
"variant": "split",
|
||||
"size": "full",
|
||||
"show_cta": true,
|
||||
"cta_text": "เริ่มต้นวันนี้",
|
||||
"cta_link": "/contact"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "page-about",
|
||||
"slug": "about",
|
||||
"data": {
|
||||
"title": "เกี่ยวกับ มอร์มินิมอร์",
|
||||
"subtitle": "บริษัท มอร์มินิมอร์ จำกัด<br>รับทำเว็บไซต์ SEO AI Chatbot สำหรับธุรกิจไทย",
|
||||
"badge": "เกี่ยวกับเรา",
|
||||
"hero_image": "/images/hero/about.jpg",
|
||||
"theme": "yellow",
|
||||
"variant": "centered",
|
||||
"size": "compact",
|
||||
"show_cta": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "page-portfolio",
|
||||
"slug": "portfolio",
|
||||
"data": {
|
||||
"title": "ผลงานของเรา",
|
||||
"subtitle": "รวมผลงานพัฒนาเว็บไซต์และโปรเจกต์ที่เราภาคภูมิใจ",
|
||||
"badge": "พอร์ตโฟลิโอ",
|
||||
"hero_image": "/images/hero/hero.jpg",
|
||||
"theme": "yellow",
|
||||
"variant": "text-only",
|
||||
"size": "compact",
|
||||
"show_cta": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "page-contact",
|
||||
"slug": "contact",
|
||||
"data": {
|
||||
"title": "พูดคุยกับเรา วันนี้เลย!",
|
||||
"subtitle": "พร้อมให้คำปรึกษาและช่วยเหลือคุณ<br>ปรึกษาฟรี ไม่มีค่าใช้จ่าย",
|
||||
"badge": "ติดต่อเรา",
|
||||
"hero_image": "/images/hero/contact.jpg",
|
||||
"theme": "yellow",
|
||||
"variant": "text-only",
|
||||
"size": "compact",
|
||||
"show_cta": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "page-faq",
|
||||
"slug": "faq",
|
||||
"data": {
|
||||
"title": "คำถามที่พบบ่อย",
|
||||
"subtitle": "หาคำตอบสำหรับคำถามที่พบบ่อยเกี่ยวกับบริการของเรา",
|
||||
"badge": "FAQ",
|
||||
"hero_image": "/images/hero/tech-consult.jpg",
|
||||
"theme": "yellow",
|
||||
"variant": "centered",
|
||||
"size": "compact",
|
||||
"show_cta": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "page-privacy",
|
||||
"slug": "privacy",
|
||||
"data": {
|
||||
"title": "นโยบายความเป็นส่วนตัว",
|
||||
"subtitle": "มีผลบังคับใช้วันที่ 5 พฤษภาคม 2569",
|
||||
"badge": "กฎหมาย",
|
||||
"hero_image": "/images/hero/ai-automation.jpg",
|
||||
"theme": "yellow",
|
||||
"variant": "text-only",
|
||||
"size": "compact",
|
||||
"show_cta": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "page-terms",
|
||||
"slug": "terms",
|
||||
"data": {
|
||||
"title": "เงื่อนไขการให้บริการ",
|
||||
"subtitle": "มีผลบังคับใช้วันที่ 5 พฤษภาคม 2569",
|
||||
"badge": "กฎหมาย",
|
||||
"hero_image": "/images/hero/marketing-automation.jpg",
|
||||
"theme": "yellow",
|
||||
"variant": "text-only",
|
||||
"size": "compact",
|
||||
"show_cta": false
|
||||
}
|
||||
}
|
||||
],
|
||||
"services": [
|
||||
{
|
||||
"id": "service-webdev",
|
||||
"slug": "webdev",
|
||||
"data": {
|
||||
"title": "พัฒนาเว็บไซต์",
|
||||
"subtitle": "สร้างเว็บไซต์ที่ทันสมัย รวดเร็ว และตอบสนองความต้องการของลูกค้าของคุณ ด้วยเทคโนโลยีล่าสุดและ design ที่สวยงาม",
|
||||
"badge": "บริการ",
|
||||
"hero_image": "/images/hero/web-development-hero.jpg",
|
||||
"feature1_icon": "⚡",
|
||||
"feature1_title": "เร็วสุดใน class",
|
||||
"feature1_desc": "โหลดเร็ว เพิ่ม conversion และ SEO ranking",
|
||||
"feature2_icon": "📱",
|
||||
"feature2_title": "Responsive ทุก device",
|
||||
"feature2_desc": "แสดงผลได้ดีบน mobile tablet และ desktop",
|
||||
"feature3_icon": "🎨",
|
||||
"feature3_title": "Design สวยงาม",
|
||||
"feature3_desc": "ออกแบบ UI/UX ที่ดึงดูดและใช้งานง่าย",
|
||||
"feature4_icon": "🔒",
|
||||
"feature4_title": "ปลอดภัย",
|
||||
"feature4_desc": "Security ระดับสูง ป้องกันการโจมตี",
|
||||
"feature5_icon": "🔍",
|
||||
"feature5_title": "SEO Optimized",
|
||||
"feature5_desc": "ออกแบบมาเพื่อให้ Google ชอบ",
|
||||
"feature6_icon": "📊",
|
||||
"feature6_title": "Analytics ในตัว",
|
||||
"feature6_desc": "ติดตามผู้เข้าชมและวัดผลได้"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "service-marketing",
|
||||
"slug": "marketing",
|
||||
"data": {
|
||||
"title": "Marketing Automation",
|
||||
"subtitle": "เพิ่มประสิทธิภาพการตลาดและลดต้นทุนด้วยระบบอัตโนมัติ ประหยัดเวลา เพิ่ม conversion วัดผลได้",
|
||||
"badge": "บริการ",
|
||||
"hero_image": "/images/hero/marketing-automation-hero.jpg",
|
||||
"feature1_icon": "📧",
|
||||
"feature1_title": "Email Automation",
|
||||
"feature1_desc": "ส่ง email อัตโนมัติเมื่อ trigger ตรงกับเงื่อนไขที่กำหนด",
|
||||
"feature2_icon": "💬",
|
||||
"feature2_title": "Chatbot Integration",
|
||||
"feature2_desc": "เชื่อมต่อ chatbot กับระบบ CRM เพื่อเก็บข้อมูลลูกค้า",
|
||||
"feature3_icon": "📱",
|
||||
"feature3_title": "SMS/Line Automation",
|
||||
"feature3_desc": "ส่ง SMS หรือ LINE message อัตโนมัติตาม timeline",
|
||||
"feature4_icon": "📊",
|
||||
"feature4_title": "Analytics Dashboard",
|
||||
"feature4_desc": "ติดตามผลแคมเปญและวัด ROI ได้แบบ real-time",
|
||||
"feature5_icon": "🎯",
|
||||
"feature5_title": "Lead Scoring",
|
||||
"feature5_desc": "ให้คะแนน leads ตามพฤติกรรมเพื่อจัดลำดับความสำคัญ",
|
||||
"feature6_icon": "🔄",
|
||||
"feature6_title": "Workflow Automation",
|
||||
"feature6_desc": "สร้าง workflow อัตโนมัติสำหรับงานที่ทำซ้ำๆ"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "service-ai",
|
||||
"slug": "ai",
|
||||
"data": {
|
||||
"title": "AI Automation",
|
||||
"subtitle": "นำ AI มาใช้เพื่อเพิ่มยอดขายและปรับปรุงการให้บริการลูกค้า เพิ่มประสิทธิภาพ ลดต้นทุน ด้วยเทคโนโลยีล้ำสมัย",
|
||||
"badge": "บริการ",
|
||||
"hero_image": "/images/hero/ai-automation-hero.jpg",
|
||||
"feature1_icon": "🤖",
|
||||
"feature1_title": "AI Chatbot",
|
||||
"feature1_desc": "Chatbot ที่ใช้ AI ตอบคำถามลูกค้าได้ 24/7 รองรับภาษาไทย",
|
||||
"feature2_icon": "💬",
|
||||
"feature2_title": "AI Customer Service",
|
||||
"feature2_desc": "ระบบตอบคำถามอัตโนมัติด้วย AI ที่เข้าใจบริบท",
|
||||
"feature3_icon": "📝",
|
||||
"feature3_title": "AI Content Generation",
|
||||
"feature3_desc": "สร้าง content อัตโนมัติด้วย AI ที่ SEO friendly",
|
||||
"feature4_icon": "📧",
|
||||
"feature4_title": "AI Email Marketing",
|
||||
"feature4_desc": "ส่ง email ที่ personalized ด้วย AI ที่วิเคราะห์พฤติกรรม",
|
||||
"feature5_icon": "📊",
|
||||
"feature5_title": "AI Sales Prediction",
|
||||
"feature5_desc": "ทำนายยอดขายและวางแผนการตลาดด้วย AI",
|
||||
"feature6_icon": "🎯",
|
||||
"feature6_title": "AI Lead Scoring",
|
||||
"feature6_desc": "ให้คะแนน leads อัตโนมัติด้วย AI ที่เรียนรู้จากข้อมูล"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "service-consult",
|
||||
"slug": "consult",
|
||||
"data": {
|
||||
"title": "Tech Consult",
|
||||
"subtitle": "ให้คำปรึกษาด้านเทคโนโลยีเพื่อธุรกิจของคุณ วางแผน ออกแบบ และ implement ระบบที่เหมาะสม",
|
||||
"badge": "บริการ",
|
||||
"hero_image": "/images/hero/tech-consult-hero.jpg",
|
||||
"feature1_icon": "🔍",
|
||||
"feature1_title": "Digital Audit",
|
||||
"feature1_desc": "วิเคราะห์สถานะดิจิทัลปัจจุบันของธุรกิจคุณอย่างละเอียด",
|
||||
"feature2_icon": "📋",
|
||||
"feature2_title": "Digital Strategy",
|
||||
"feature2_desc": "วางแผน digital transformation ที่เหมาะกับเป้าหมายธุรกิจ",
|
||||
"feature3_icon": "🛠️",
|
||||
"feature3_title": "Technology Selection",
|
||||
"feature3_desc": "แนะนำเทคโนโลยีที่เหมาะสมกับ budget และความต้องการ",
|
||||
"feature4_icon": "📐",
|
||||
"feature4_title": "System Architecture",
|
||||
"feature4_desc": "ออกแบบระบบที่ scalable และ maintainable",
|
||||
"feature5_icon": "🔧",
|
||||
"feature5_title": "Implementation Support",
|
||||
"feature5_desc": "ดูแลและให้คำปรึกษาตลอดการ implement",
|
||||
"feature6_icon": "📈",
|
||||
"feature6_title": "Performance Optimization",
|
||||
"feature6_desc": "ปรับปรุงประสิทธิภาพระบบให้ดีขึ้นอย่างต่อเนื่อง"
|
||||
}
|
||||
}
|
||||
],
|
||||
"portfolio": [
|
||||
{
|
||||
"id": "portfolio-001",
|
||||
"slug": "lungfinler",
|
||||
"data": {
|
||||
"name": "Lungfinler",
|
||||
"url": "https://lungfinler.com",
|
||||
"category": "webdev",
|
||||
"category_label": "พัฒนาเว็บไซต์",
|
||||
"thumbnail": "/images/portfolio/lungfinler.png",
|
||||
"description": "Digital Agency - บริการด้านการสร้างแบรนด์ กราฟิกดีไซน์ และถ่ายภาพสินค้าคุณภาพสูง"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "portfolio-002",
|
||||
"slug": "jetindustries",
|
||||
"data": {
|
||||
"name": "Jet Industries",
|
||||
"url": "https://jetindustries.co.th",
|
||||
"category": "webdev",
|
||||
"category_label": "พัฒนาเว็บไซต์",
|
||||
"thumbnail": "/images/portfolio/jetindustries.png",
|
||||
"description": "ผู้ผลิตพลาสติกฉีดขึ้นรูปอย่างแม่นยำ (Precision Plastic Injection Molding) มีประสบการณ์กว่า 40 ปี"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "portfolio-003",
|
||||
"slug": "lawyernoom",
|
||||
"data": {
|
||||
"name": "สำนักงานกฎหมาย ตถาตา",
|
||||
"url": "https://lawyernoom.com",
|
||||
"category": "webdev",
|
||||
"category_label": "พัฒนาเว็บไซต์",
|
||||
"thumbnail": "/images/portfolio/lawyernoom.png",
|
||||
"description": "สำนักงานกฎหมายโดย ทนายความ คมสัน ศรีวนิชย์ - บริการด้านคดีความ คดีแพ่ง คดีอาญา"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "portfolio-004",
|
||||
"slug": "underdog",
|
||||
"data": {
|
||||
"name": "Underdog Marketing",
|
||||
"url": "https://underdog.run",
|
||||
"category": "webdev",
|
||||
"category_label": "พัฒนาเว็บไซต์",
|
||||
"thumbnail": "/images/portfolio/underdog.png",
|
||||
"description": "บล็อกการตลาดและการขายสไตล์ ลุยไม่ยั้ง โดย บุ้ง ดีดติ่งหู"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "portfolio-005",
|
||||
"slug": "baofuling",
|
||||
"data": {
|
||||
"name": "Baofuling Shop",
|
||||
"url": "https://baofulingshop.com",
|
||||
"category": "ecommerce",
|
||||
"category_label": "อีคอมเมิร์ซ",
|
||||
"thumbnail": "/images/portfolio/baofuling.png",
|
||||
"description": "ร้านค้าออนไลน์ครีมบัวหิมะและผลิตภัณฑ์ความงามจีน"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "portfolio-006",
|
||||
"slug": "trainersunny",
|
||||
"data": {
|
||||
"name": "เทรนเนอร์ซันนี่",
|
||||
"url": "https://trainersunny.com",
|
||||
"category": "webdev",
|
||||
"category_label": "พัฒนาเว็บไซต์",
|
||||
"thumbnail": "/images/portfolio/trainersunny.png",
|
||||
"description": "ผู้เชี่ยวชาญด้านการพัฒนาบุคลากรและ Soft Skill"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "portfolio-007",
|
||||
"slug": "luadjob",
|
||||
"data": {
|
||||
"name": "เลือดจระเข้วานิไทย",
|
||||
"url": "https://เลือดจระเข้วานิไทย.com",
|
||||
"category": "ecommerce",
|
||||
"category_label": "อีคอมเมิร์ซ",
|
||||
"thumbnail": "/images/portfolio/luadjob.png",
|
||||
"description": "ตัวแทนจำหน่ายเลือดจระเข้วานิไทยอย่างเป็นทางการ"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "portfolio-008",
|
||||
"slug": "tuanthong",
|
||||
"data": {
|
||||
"name": "ทวนทอง 99",
|
||||
"url": "https://tuanthong99.com",
|
||||
"category": "ecommerce",
|
||||
"category_label": "อีคอมเมิร์ซ",
|
||||
"thumbnail": "/images/portfolio/tuanthong.png",
|
||||
"description": "ร้านค้าออนไลน์สมุนไพรไทยคุณภาพสูง"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "portfolio-009",
|
||||
"slug": "odooportal",
|
||||
"data": {
|
||||
"name": "Odoo Portal",
|
||||
"url": "https://odooportal.com",
|
||||
"category": "marketing",
|
||||
"category_label": "ที่ปรึกษาการตลาด",
|
||||
"thumbnail": "/images/portfolio/odooportal.png",
|
||||
"description": "ตัวแทนจำหน่าย Odoo อย่างเป็นทางการในประเทศไทย"
|
||||
}
|
||||
}
|
||||
],
|
||||
"faq": [
|
||||
{
|
||||
"id": "faq-001",
|
||||
"slug": "service-001",
|
||||
"data": { "category": "บริการ", "category_icon": "🎯", "question": "MoreminiMore ให้บริการอะไรบ้าง?", "answer": "เราให้บริการ 4 ประเภทหลัก: พัฒนาเว็บไซต์, Marketing Automation, AI Automation และ Tech Consult สำหรับธุรกิจไทย" }
|
||||
},
|
||||
{
|
||||
"id": "faq-002",
|
||||
"slug": "service-002",
|
||||
"data": { "category": "บริการ", "category_icon": "🎯", "question": "สามารถสั่งทำเว็บไซต์เฉพาะประเภทได้ไหม?", "answer": "ได้ เราสามารถพัฒนาเว็บไซต์ได้ทุกประเภท ไม่ว่าจะเป็นเว็บบริษัท เว็บขายของ เว็บ Landing Page หรือระบบ Web Application" }
|
||||
},
|
||||
{
|
||||
"id": "faq-003",
|
||||
"slug": "service-003",
|
||||
"data": { "category": "บริการ", "category_icon": "🎯", "question": "AI Chatbot สามารถทำอะไรได้บ้าง?", "answer": "AI Chatbot ของเราสามารถตอบคำถามลูกค้า รับออร์เดอร์ นัดหมาย และเชื่อมต่อกับระบบ CRM หรือร้านค้าออนไลน์ได้" }
|
||||
},
|
||||
{
|
||||
"id": "faq-004",
|
||||
"slug": "price-001",
|
||||
"data": { "category": "ราคา", "category_icon": "💰", "question": "ราคาเริ่มต้นของการทำเว็บไซต์เท่าไหร่?", "answer": "ราคาเริ่มต้นอยู่ที่ 15,000 บาท ขึ้นอยู่กับความซับซ้อนและฟีเจอร์ที่ต้องการ เราจะประเมินและเสนอราคาหลังจากการปรึกษาฟรี" }
|
||||
},
|
||||
{
|
||||
"id": "faq-005",
|
||||
"slug": "price-002",
|
||||
"data": { "category": "ราคา", "category_icon": "💰", "question": "มีราคาแพ็คเกจหรือไม่?", "answer": "มี เรามีแพ็คเกจสำหรับธุรกิจที่ต้องการเริ่มต้นอย่างง่ายๆ และแพ็คเกจสำหรับธุรกิจที่ต้องการระบบครบวงจร สามารถเลือกได้ตามความต้องการ" }
|
||||
},
|
||||
{
|
||||
"id": "faq-006",
|
||||
"slug": "price-003",
|
||||
"data": { "category": "ราคา", "category_icon": "💰", "question": "ชำระเงินอย่างไร?", "answer": "รองรับการชำระเงินผ่านโอนเงินธนาคาร หรือผ่อนชำระผ่านบัตรเครดิต 3-6 งวด (มีดอกเบี้ย)" }
|
||||
},
|
||||
{
|
||||
"id": "faq-007",
|
||||
"slug": "time-001",
|
||||
"data": { "category": "ระยะเวลา", "category_icon": "⏱️", "question": "ใช้เวลาพัฒนานานเท่าไหร่?", "answer": "ขึ้นอยู่กับความซับซ้อน Landing Page ใช้เวลา 1-2 สัปดาห์ เว็บไซต์ขนาดกลาง 2-4 สัปดาห์ ระบบ Web Application 4-8 สัปดาห์" }
|
||||
},
|
||||
{
|
||||
"id": "faq-008",
|
||||
"slug": "time-002",
|
||||
"data": { "category": "ระยะเวลา", "category_icon": "⏱️", "question": "ถ้าต้องการด่วนได้ไหม?", "answer": "ได้ เรามีบริการด่วนพิเศษ (เพิ่มค่าใช้จ่าย 30%) สามารถส่งมอบงานได้เร็วขึ้น 50%" }
|
||||
},
|
||||
{
|
||||
"id": "faq-009",
|
||||
"slug": "support-001",
|
||||
"data": { "category": "หลังการขาย", "category_icon": "💬", "question": "มีการรับประกันหรือไม่?", "answer": "เรารับประกันงาน 30 วันหลังส่งมอบ หากมีปัญหาจากการพัฒนา เราจะแก้ไขให้ฟรี" }
|
||||
},
|
||||
{
|
||||
"id": "faq-010",
|
||||
"slug": "support-002",
|
||||
"data": { "category": "หลังการขาย", "category_icon": "💬", "question": "มีบริการดูแลหลังการขายไหม?", "answer": "มี เรามีแพ็คเกจดูแลรายเดือนเริ่มต้นที่ 2,000 บาท/เดือน รวมการอัพเดทเนื้อหา ปรับปรุงความปลอดภัย และ Backup" }
|
||||
}
|
||||
],
|
||||
"blog": [
|
||||
{
|
||||
"id": "post-001",
|
||||
"slug": "5-ways-ai-increase-sales",
|
||||
"data": {
|
||||
"title": "5 วิธีใช้ AI เพิ่มยอดขายให้ธุรกิจของคุณ",
|
||||
"excerpt": "ค้นพบ 5 วิธีที่ AI สามารถช่วยเพิ่มยอดขายให้ธุรกิจ SMEs ไทย พร้อมตัวอย่างและแนวทางการนำไปใช้จริง",
|
||||
"image": "/images/blog/5-ways-ai-increase-sales.jpg",
|
||||
"date": "2026-03-11",
|
||||
"category": "AI Business",
|
||||
"content": {
|
||||
"type": "doc",
|
||||
"content": [
|
||||
{ "type": "heading", "attrs": { "level": 2 }, "content": [{ "type": "text", "text": "วิธีที่ 1: ใช้ AI วิเคราะห์ลูกค้าและแนะนำสินค้าที่ตรงใจ" }] },
|
||||
{ "type": "paragraph", "content": [{ "type": "text", "text": "หนึ่งในความสามารถที่ทรงพลังที่สุดของ AI คือการวิเคราะห์ข้อมูลลูกค้าและค้นหารูปแบบที่มนุษย์อาจมองไม่เห็น AI สามารถวิเคราะห์ว่าลูกค้าแต่ละคนชอบสินค้าประเภทไหน ซื้อในช่วงเวลาไหน และมีพฤติกรรมการซื้ออย่างไร" }] },
|
||||
{ "type": "heading", "attrs": { "level": 2 }, "content": [{ "type": "text", "text": "วิธีที่ 2: ใช้ Chatbot ดูแลลูกค้าตลอด 24 ชั่วโมง" }] },
|
||||
{ "type": "paragraph", "content": [{ "type": "text", "text": "ลูกค้าจำนวนมากต้องการได้รับคำตอบทันที ไม่ว่าจะกี่โมง แต่การจ้างพนักงานทำงาน 24 ชั่วโมงนั้นมีค่าใช้จ่ายสูง Chatbot ที่ใช้ AI สามารถตอบคำถามลูกค้าได้ตลอดเวลา โดยไม่ต้องเสียค่าล่วงเวลา" }] },
|
||||
{ "type": "heading", "attrs": { "level": 2 }, "content": [{ "type": "text", "text": "วิธีที่ 3: ใช้ AI ส่งข้อความการตลาดในเวลาที่เหมาะสม" }] },
|
||||
{ "type": "paragraph", "content": [{ "type": "text", "text": "การส่งข้อความการตลาดไม่ใช่แค่การส่งออกไปเท่านั้น แต่ต้องส่งในเวลาที่ลูกค้ามีโอกาสอ่านและตอบสนองมากที่สุด AI สามารถวิเคราะห์ว่าลูกค้าแต่ละคนมีช่วงเวลาไหนที่เปิดอ่านข้อความบ่อยที่สุด และส่งในเวลานั้น" }] },
|
||||
{ "type": "heading", "attrs": { "level": 2 }, "content": [{ "type": "text", "text": "วิธีที่ 4: ใช้ AI สร้างเนื้อหาการตลาด" }] },
|
||||
{ "type": "paragraph", "content": [{ "type": "text", "text": "เนื้อหาการตลาดที่ดีเป็นหัวใจสำคัญในการดึงดูดลูกค้า แต่การสร้างเนื้อหาที่มีคุณภาพตลอดเวลาต้องใช้เวลาและทรัพยากรมาก AI สามารถช่วยสร้างเนื้อหาได้เร็วขึ้น ไม่ว่าจะเป็นโพสต์เฟซบุ๊ก คำบรรยายสินค้า อีเมลการตลาด หรือบทความบล็อก" }] },
|
||||
{ "type": "heading", "attrs": { "level": 2 }, "content": [{ "type": "text", "text": "วิธีที่ 5: ใช้ AI ทำนายแนวโน้มและวางแผนสินค้า" }] },
|
||||
{ "type": "paragraph", "content": [{ "type": "text", "text": "การมีสินค้าคงคลงเป็นสิ่งจำเป็นสำหรับธุรกิจค้าปลีก แต่การมีสินค้ามากเกินไปก็เป็นปัญหา AI สามารถวิเคราะห์ข้อมูลยอดขายในอดีต ฤดูกาล และปัจจัยอื่นๆ เพื่อทำนายว่าควรสั่งสินค้าเท่าไหร่ในแต่ละช่วง" }] }
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "post-002",
|
||||
"slug": "ai-content-google-love",
|
||||
"data": {
|
||||
"title": "วิธีสร้าง Content ด้วย AI ที่ Google รัก",
|
||||
"excerpt": "เรียนรู้วิธีการใช้ AI ช่วยสร้างเนื้อหาการตลาดที่มีคุณภาพและได้รับการจัดอันดับดีจาก Google พร้อมเทคนิคและตัวอย่างจริง",
|
||||
"image": "/images/blog/ai-content-google-love.jpg",
|
||||
"date": "2026-03-10",
|
||||
"category": "AI Content",
|
||||
"content": {
|
||||
"type": "doc",
|
||||
"content": [
|
||||
{ "type": "heading", "attrs": { "level": 2 }, "content": [{ "type": "text", "text": "ทำไม AI Content ต้องมีคุณภาพ" }] },
|
||||
{ "type": "paragraph", "content": [{ "type": "text", "text": "Google มีอัลกอริทึมที่ฉลาดมาก สามารถแยกแยะได้ว่าเนื้อหาที่สร้างโดย AI มีคุณภาพหรือไม่ เนื้อหาที่ไม่มีคุณค่า สร้างขึ้นแค่เพื่อใส่คีย์เวิร์ด จะถูกลงโทษและไม่ติดอันดับ" }] },
|
||||
{ "type": "heading", "attrs": { "level": 2 }, "content": [{ "type": "text", "text": "วิธีใช้ AI สร้างเนื้อหาที่ดี" }] },
|
||||
{ "type": "paragraph", "content": [{ "type": "text", "text": "ใช้ AI เป็นผู้ช่วย ไม่ใช่ผู้เขียนทั้งหมด วิธีที่ดีที่สุดคือใช้ AI ช่วยในบางส่วน เช่น รวบรวมข้อมูล สร้างโครงสร้าง หรือเขียน draft แล้วนำมาปรับแก้ด้วยมนุษย์" }] }
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "post-003",
|
||||
"slug": "ai-for-sme-thailand",
|
||||
"data": {
|
||||
"title": "AI สำหรับ SME ไทย: คู่มือฉบับสมบูรณ์",
|
||||
"excerpt": "การใช้ AI สำหรับธุรกิจ SME ไทยเพื่อเพิ่มขีดความสามารถในการแข่งขัน พร้อมแนวทางปฏิบัติจริง",
|
||||
"image": "/images/blog/ai-for-sme-thailand.jpg",
|
||||
"date": "2026-03-08",
|
||||
"category": "AI Business",
|
||||
"content": {
|
||||
"type": "doc",
|
||||
"content": [
|
||||
{ "type": "heading", "attrs": { "level": 2 }, "content": [{ "type": "text", "text": "ทำไม SME ต้องใช้ AI" }] },
|
||||
{ "type": "paragraph", "content": [{ "type": "text", "text": "AI ไม่ใช่เทคโนโลยีสำหรับบริษัทใหญ่เท่านั้น ธุรกิจ SME สามารถเริ่มใช้ประโยชน์จาก AI ได้ง่ายๆ ด้วยเครื่องมือที่เข้าถึงได้" }] }
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "post-004",
|
||||
"slug": "digital-transformation-guide",
|
||||
"data": {
|
||||
"title": "คู่มือ Digital Transformation ฉบับสมบูรณ์",
|
||||
"excerpt": "การ transform ธุรกิจของคุณสู่ดิจิทัลอย่างครบวงจร ตั้งแต่การวางแผนจนถึงการ Implement",
|
||||
"image": "/images/blog/digital-transformation.jpg",
|
||||
"date": "2026-03-05",
|
||||
"category": "Business",
|
||||
"content": {
|
||||
"type": "doc",
|
||||
"content": [
|
||||
{ "type": "heading", "attrs": { "level": 2 }, "content": [{ "type": "text", "text": "Digital Transformation คืออะไร" }] },
|
||||
{ "type": "paragraph", "content": [{ "type": "text", "text": "Digital Transformation คือการนำเทคโนโลยีดิจิทัลมาใช้ในทุกด้านของธุรกิจ เพื่อเพิ่มประสิทธิภาพและสร้างคุณค่าใหม่ให้กับลูกค้า" }] }
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "post-005",
|
||||
"slug": "marketing-automation-guide",
|
||||
"data": {
|
||||
"title": "Marketing Automation: คู่มือเริ่มต้น",
|
||||
"excerpt": "เรียนรู้พื้นฐานของ Marketing Automation และวิธีเริ่มต้นใช้งานสำหรับธุรกิจของคุณ",
|
||||
"image": "/images/blog/marketing-automation-guide.jpg",
|
||||
"date": "2026-03-01",
|
||||
"category": "Marketing",
|
||||
"content": {
|
||||
"type": "doc",
|
||||
"content": [
|
||||
{ "type": "heading", "attrs": { "level": 2 }, "content": [{ "type": "text", "text": "Marketing Automation คืออะไร" }] },
|
||||
{ "type": "paragraph", "content": [{ "type": "text", "text": "Marketing Automation คือการใช้ซอฟต์แวร์เพื่อ automate การตลาดซ้ำๆ เช่น การส่งอีเมล การโพสต์โซเชียลมีเดีย และการวิเคราะห์ข้อมูล" }] }
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
4
.gitignore
vendored
@@ -22,3 +22,7 @@ pnpm-debug.log*
|
||||
|
||||
# jetbrains setting folder
|
||||
.idea/
|
||||
.hermes/
|
||||
|
||||
# archive (large local files)
|
||||
_archive/
|
||||
|
||||
22
PLAN-REVIEW-LOG.md
Normal file
@@ -0,0 +1,22 @@
|
||||
# Plan Review Log: Footer Component + Remove Yellow Lines from Process Section
|
||||
Act 1 (grill) complete — plan locked with the user. MAX_ROUNDS=5.
|
||||
|
||||
## Round 1 — Codex
|
||||
พบ 10 issues (3 critical, 3 significant, 4 minor):
|
||||
1. 🔴 PageShell layout ignored — ควรแก้ผ่าน PageShell
|
||||
2. 🔴 Privacy/Terms pages ไม่มี — dead links
|
||||
3. 🔴 Liquid glass markup pattern ไม่ระบุ
|
||||
4. 🟡 service-proof-grid yellow accent missed
|
||||
5. 🟡 Mobile layout spec ambiguous
|
||||
6. 🟡 Step-flow visual cue removed without alternative
|
||||
7. 🟡 Missing semantic `<footer>` element
|
||||
8. 🟠 LINE URL unspecified
|
||||
9. 🟠 Logo dimensions omitted
|
||||
10. 🟠 z-index risk unresolved
|
||||
|
||||
### Claude's response
|
||||
แก้ทั้ง 10 ข้อใน PLAN.md revision
|
||||
|
||||
## Round 2 — Codex
|
||||
All 10 findings addressed. Minor note: footer ควรวางระหว่าง `</main>` กับ floating-cta (ไม่ใช่ inside `<main>`).
|
||||
VERDICT: APPROVED (2 rounds)
|
||||
71
PLAN.md
Normal file
@@ -0,0 +1,71 @@
|
||||
# Plan: Footer Component + Remove Yellow Lines from Process Section
|
||||
_Locked via grill — by Claude + Kunthawat — Revised Round 1_
|
||||
|
||||
## Goal
|
||||
สร้าง Footer component ใหม่ด้วย liquid glass style และลบเส้นสีเหลืองออกจาก How we work section
|
||||
|
||||
## Approach
|
||||
### 1. ลบเส้นสีเหลืองจาก Process Section (`src/styles/global.css`)
|
||||
- ลบ `.process-grid::before` (เส้นแนวนอนสีเหลือง) → `display: none`
|
||||
- ลบ `.process-grid article::after` (วงกลม ">" สีเหลืองระหว่าง step) → `display: none`
|
||||
- `.process-grid .step-number`: เปลี่ยน `background: var(--yellow)` → `background: rgb(255 255 255 / .5)` + ลบ yellow box-shadow
|
||||
- `.service-proof-grid .process-grid .step-number`: override สีเหลืองเหมือนกัน (scope เพิ่ม)
|
||||
- **หมายเหตุ:** step numbers (01, 02, 03, 04) ยังคงแสดง sequential flow อยู่แล้ว ไม่ต้องเพิ่ม connector แทน
|
||||
|
||||
### 2. สร้าง Footer Component (`src/components/Footer.astro`)
|
||||
- ใช้ `<footer>` semantic element
|
||||
- ใช้ liquid glass style (ต้องมี 3 child divs):
|
||||
```html
|
||||
<footer class="site-footer liquid-glass liquidGlass-wrapper">
|
||||
<div class="liquidGlass-effect" aria-hidden="true"></div>
|
||||
<div class="liquidGlass-tint" aria-hidden="true"></div>
|
||||
<div class="liquidGlass-shine" aria-hidden="true"></div>
|
||||
<!-- content -->
|
||||
</footer>
|
||||
```
|
||||
- `position: relative; z-index: auto` (ไม่ทับ lead-panel z-index: 110)
|
||||
|
||||
### 3. เนื้อหา Footer
|
||||
**ซ้าย:**
|
||||
- โลโก้: `/images/logos/logo-long-black.png` (width="205" height="36")
|
||||
- คำอธิบาย: "ที่ปรึกษาเว็บไซต์ การตลาด และ AI สำหรับ SME"
|
||||
|
||||
**กลาง:**
|
||||
- ลิงก์: หน้าแรก / บริการ / ผลงาน / บล็อก / ติดต่อ / นโยบายความเป็นส่วนตัว / เงื่อนไขการใช้งาน
|
||||
|
||||
**ขวา:**
|
||||
- LINE: @moreminimore (link: https://line.me/ti/p/@moreminimore)
|
||||
- Email: contact@moreminimore.com
|
||||
|
||||
**ล่าง:**
|
||||
- Copyright: © {new Date().getFullYear()} MoreminiMore
|
||||
|
||||
### 4. Responsive
|
||||
- Desktop (>768px): 3 columns (grid-template-columns: 1fr 1fr 1fr)
|
||||
- Mobile (≤768px): vertical stack (flex-direction: column) — เรียง: โลโก้ → ลิงก์ → ติดต่อ → copyright
|
||||
|
||||
### 5. Integration Strategy
|
||||
- **PageShell pages** (about, services, blog, blog/[slug], contact, faq, portfolio, services/[slug]):
|
||||
เพิ่ม `<Footer />` import + render ใน `src/components/PageShell.astro` ก่อน `</main>` หรือก่อน `</body>`
|
||||
- **index.astro** (standalone, ไม่ใช้ PageShell):
|
||||
เพิ่ม `<Footer />` import + render ก่อน `</body>` โดยตรง
|
||||
|
||||
### 6. สร้าง Placeholder Pages
|
||||
- สร้าง `src/pages/privacy.astro` (placeholder — "นโยบายความเป็นส่วนตัว กำลังอัพเดท")
|
||||
- สร้าง `src/pages/terms.astro` (placeholder — "เงื่อนไขการใช้งาน กำลังอัพเดท")
|
||||
- ใช้ PageShell layout เหมือนหน้าอื่น
|
||||
|
||||
## Key decisions & tradeoffs
|
||||
- ใช้ liquid glass style เดียวกับ navbar เพื่อความ cohesive
|
||||
- ลบเส้นเหลืองทั้งหมด — step numbers ยังบ่งบอกลำดับอยู่
|
||||
- ใช้ dynamic year (`new Date().getFullYear()`) ใน copyright (Astro SSG → build-time inlined)
|
||||
- Footer ใน PageShell = แก้จุดเดียว ครอบคลุม 8 หน้า
|
||||
- z-index: auto (ไม่ทับ lead-panel)
|
||||
|
||||
## Risks / open questions
|
||||
- Privacy/Terms pages เป็น placeholder — ต้องเพิ่ม content ทีหลัง
|
||||
- Logo อาจต้องเปลี่ยนเป็นสีขาวเมื่ออยู่บนพื้นเข้ม (invert)
|
||||
|
||||
## Out of scope
|
||||
- ไม่แก้ไขหน้า Privacy/Terms content จริง
|
||||
- ไม่เพิ่ม social media icons (Facebook/X/LinkedIn)
|
||||
43
README.md
@@ -1,43 +0,0 @@
|
||||
# Astro Starter Kit: Minimal
|
||||
|
||||
```sh
|
||||
npm create astro@latest -- --template minimal
|
||||
```
|
||||
|
||||
> 🧑🚀 **Seasoned astronaut?** Delete this file. Have fun!
|
||||
|
||||
## 🚀 Project Structure
|
||||
|
||||
Inside of your Astro project, you'll see the following folders and files:
|
||||
|
||||
```text
|
||||
/
|
||||
├── public/
|
||||
├── src/
|
||||
│ └── pages/
|
||||
│ └── index.astro
|
||||
└── package.json
|
||||
```
|
||||
|
||||
Astro looks for `.astro` or `.md` files in the `src/pages/` directory. Each page is exposed as a route based on its file name.
|
||||
|
||||
There's nothing special about `src/components/`, but that's where we like to put any Astro/React/Vue/Svelte/Preact components.
|
||||
|
||||
Any static assets, like images, can be placed in the `public/` directory.
|
||||
|
||||
## 🧞 Commands
|
||||
|
||||
All commands are run from the root of the project, from a terminal:
|
||||
|
||||
| Command | Action |
|
||||
| :------------------------ | :----------------------------------------------- |
|
||||
| `npm install` | Installs dependencies |
|
||||
| `npm run dev` | Starts local dev server at `localhost:4321` |
|
||||
| `npm run build` | Build your production site to `./dist/` |
|
||||
| `npm run preview` | Preview your build locally, before deploying |
|
||||
| `npm run astro ...` | Run CLI commands like `astro add`, `astro check` |
|
||||
| `npm run astro -- --help` | Get help using the Astro CLI |
|
||||
|
||||
## 👀 Want to learn more?
|
||||
|
||||
Feel free to check [our documentation](https://docs.astro.build) or jump into our [Discord server](https://astro.build/chat).
|
||||
@@ -1,27 +1,8 @@
|
||||
// @ts-check
|
||||
import { defineConfig } from 'astro/config';
|
||||
import react from "@astrojs/react";
|
||||
import mdx from "@astrojs/mdx";
|
||||
import node from "@astrojs/node";
|
||||
import emdash, { local } from "emdash/astro";
|
||||
import { sqlite } from "emdash/db";
|
||||
|
||||
export default defineConfig({
|
||||
output: "server",
|
||||
adapter: node({
|
||||
mode: 'standalone'
|
||||
}),
|
||||
integrations: [
|
||||
react(),
|
||||
mdx(),
|
||||
emdash({
|
||||
database: sqlite({ url: "file:./data.db" }),
|
||||
storage: local({
|
||||
directory: "./uploads",
|
||||
baseUrl: "/_emdash/api/media/file",
|
||||
}),
|
||||
}),
|
||||
],
|
||||
image: { layout: "constrained", responsiveStyles: true },
|
||||
devToolbar: { enabled: true },
|
||||
});
|
||||
output: 'static',
|
||||
image: { layout: 'constrained', responsiveStyles: true },
|
||||
devToolbar: { enabled: false },
|
||||
});
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
const seed = require('./seed/seed.json');
|
||||
const Database = require('better-sqlite3');
|
||||
const db = new Database('./data.db');
|
||||
|
||||
const cols = ['title','subtitle','badge','hero_image',
|
||||
'feature1_icon','feature1_title','feature1_desc',
|
||||
'feature2_icon','feature2_title','feature2_desc',
|
||||
'feature3_icon','feature3_title','feature3_desc',
|
||||
'feature4_icon','feature4_title','feature4_desc',
|
||||
'feature5_icon','feature5_title','feature5_desc',
|
||||
'feature6_icon','feature6_title','feature6_desc'];
|
||||
|
||||
const placeholders = cols.map(() => '?').join(', ');
|
||||
const sql = `INSERT OR REPLACE INTO ec_services (id, slug, status, ${cols.join(', ')}, created_at, updated_at, published_at) VALUES (?, ?, 'published', ${placeholders}, datetime('now'), datetime('now'), datetime('now'))`;
|
||||
|
||||
console.log('Columns:', 3 + cols.length); // id, slug, status + cols
|
||||
console.log('SQL placeholders:', (sql.match(/\?/g) || []).length);
|
||||
|
||||
db.close();
|
||||
BIN
data.db-shm
116
emdash-env.d.ts
vendored
@@ -1,116 +0,0 @@
|
||||
// Generated by EmDash on dev server start
|
||||
// Do not edit manually
|
||||
|
||||
/// <reference types="emdash/locals" />
|
||||
|
||||
import type { ContentBylineCredit, PortableTextBlock } from "emdash";
|
||||
|
||||
export interface Blog {
|
||||
id: string;
|
||||
slug: string | null;
|
||||
status: string;
|
||||
title?: string;
|
||||
excerpt?: string;
|
||||
image?: { id: string; src?: string; alt?: string; width?: number; height?: number; provider?: string; previewUrl?: string; meta?: Record<string, unknown> };
|
||||
date?: string;
|
||||
category?: string;
|
||||
content?: PortableTextBlock[];
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
publishedAt: Date | null;
|
||||
bylines?: ContentBylineCredit[];
|
||||
}
|
||||
|
||||
export interface Faq {
|
||||
id: string;
|
||||
slug: string | null;
|
||||
status: string;
|
||||
category?: string;
|
||||
question?: string;
|
||||
answer?: string;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
publishedAt: Date | null;
|
||||
bylines?: ContentBylineCredit[];
|
||||
}
|
||||
|
||||
export interface Page {
|
||||
id: string;
|
||||
slug: string | null;
|
||||
status: string;
|
||||
title?: string;
|
||||
subtitle?: string;
|
||||
badge?: string;
|
||||
hero_image?: { id: string; src?: string; alt?: string; width?: number; height?: number; provider?: string; previewUrl?: string; meta?: Record<string, unknown> };
|
||||
theme?: string;
|
||||
show_cta?: boolean;
|
||||
cta_text?: string;
|
||||
cta_link?: string;
|
||||
variant?: string;
|
||||
size?: string;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
publishedAt: Date | null;
|
||||
bylines?: ContentBylineCredit[];
|
||||
}
|
||||
|
||||
export interface Portfolio {
|
||||
id: string;
|
||||
slug: string | null;
|
||||
status: string;
|
||||
name?: string;
|
||||
url?: string;
|
||||
category?: string;
|
||||
category_label?: string;
|
||||
thumbnail?: { id: string; src?: string; alt?: string; width?: number; height?: number; provider?: string; previewUrl?: string; meta?: Record<string, unknown> };
|
||||
description?: string;
|
||||
services?: unknown;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
publishedAt: Date | null;
|
||||
bylines?: ContentBylineCredit[];
|
||||
}
|
||||
|
||||
export interface Service {
|
||||
id: string;
|
||||
slug: string | null;
|
||||
status: string;
|
||||
title?: string;
|
||||
subtitle?: string;
|
||||
badge?: string;
|
||||
hero_image?: { id: string; src?: string; alt?: string; width?: number; height?: number; provider?: string; previewUrl?: string; meta?: Record<string, unknown> };
|
||||
content?: PortableTextBlock[];
|
||||
features?: unknown;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
publishedAt: Date | null;
|
||||
bylines?: ContentBylineCredit[];
|
||||
}
|
||||
|
||||
export interface Setting {
|
||||
id: string;
|
||||
slug: string | null;
|
||||
status: string;
|
||||
site_name?: string;
|
||||
email?: string;
|
||||
phone?: string;
|
||||
address?: string;
|
||||
facebook?: string;
|
||||
line?: string;
|
||||
linkedin?: string;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
publishedAt: Date | null;
|
||||
bylines?: ContentBylineCredit[];
|
||||
}
|
||||
|
||||
declare module "emdash" {
|
||||
interface EmDashCollections {
|
||||
blog: Blog;
|
||||
faq: Faq;
|
||||
pages: Page;
|
||||
portfolio: Portfolio;
|
||||
services: Service;
|
||||
settings: Setting;
|
||||
}
|
||||
}
|
||||
153
google-apps-script/SETUP.md
Normal file
@@ -0,0 +1,153 @@
|
||||
# Google Apps Script Lead Form Setup
|
||||
|
||||
ใช้ไฟล์นี้เพื่อตั้งระบบรับ lead จากฟอร์ม MoreminiMore แบบง่ายก่อน โดยให้ Google Apps Script บันทึกข้อมูลลง Google Sheet และส่งอีเมลแจ้งเตือนเข้า Gmail/Google Workspace
|
||||
|
||||
อ้างอิง official docs:
|
||||
|
||||
- Apps Script Web App deployment: https://developers.google.com/apps-script/guides/web
|
||||
- Apps Script MailApp: https://developers.google.com/apps-script/reference/mail/mail-app
|
||||
|
||||
## สิ่งที่ต้องมี
|
||||
|
||||
- Google account หรือ Google Workspace account ที่จะใช้รับ lead
|
||||
- แนะนำให้ใช้บัญชีของโดเมนบริษัท เช่น `contact@moreminimore.com`
|
||||
- Google Sheet ใหม่ 1 ไฟล์ สำหรับเก็บ lead
|
||||
|
||||
## ขั้นตอนติดตั้ง
|
||||
|
||||
### 1. สร้าง Google Sheet
|
||||
|
||||
1. เข้า Google Drive
|
||||
2. สร้าง Google Sheet ใหม่
|
||||
3. ตั้งชื่อเช่น `MoreminiMore Website Leads`
|
||||
4. ไม่ต้องสร้าง column เอง script จะสร้าง header ให้ตอนมี lead แรก
|
||||
|
||||
### 2. เปิด Apps Script จาก Sheet
|
||||
|
||||
1. ใน Google Sheet ไปที่ `Extensions`
|
||||
2. เลือก `Apps Script`
|
||||
3. จะเปิดหน้า Apps Script editor
|
||||
4. ลบโค้ดเดิมใน `Code.gs`
|
||||
5. Copy โค้ดทั้งหมดจาก `google-apps-script/lead-form.gs`
|
||||
6. Paste ลงใน `Code.gs`
|
||||
|
||||
### 3. แก้อีเมลผู้รับ
|
||||
|
||||
ในไฟล์ `Code.gs` หา:
|
||||
|
||||
```js
|
||||
const CONFIG = {
|
||||
RECIPIENT_EMAIL: 'contact@moreminimore.com',
|
||||
```
|
||||
|
||||
เปลี่ยน `RECIPIENT_EMAIL` เป็นอีเมลที่จะรับแจ้งเตือน lead
|
||||
|
||||
ถ้าใช้ `contact@moreminimore.com` อยู่แล้ว ไม่ต้องแก้
|
||||
|
||||
### 4. Save project
|
||||
|
||||
1. กด Save
|
||||
2. ตั้งชื่อ project เช่น `MoreminiMore Lead Form`
|
||||
|
||||
### 5. Deploy เป็น Web App
|
||||
|
||||
ตาม official docs ของ Google ให้ deploy web app โดย:
|
||||
|
||||
1. มุมขวาบน กด `Deploy`
|
||||
2. เลือก `New deployment`
|
||||
3. ตรง `Select type` กด icon ตั้งค่า แล้วเลือก `Web app`
|
||||
4. ตั้งค่า:
|
||||
- Description: `MoreminiMore lead form endpoint`
|
||||
- Execute as: `Me`
|
||||
- Who has access: `Anyone`
|
||||
5. กด `Deploy`
|
||||
6. Google จะขอ authorize permissions
|
||||
7. เลือก account ของคุณ
|
||||
8. อนุญาตสิทธิ์ที่เกี่ยวกับ Google Sheets และส่งอีเมล
|
||||
9. Copy `Web app URL` เก็บไว้
|
||||
|
||||
URL จะหน้าตาประมาณ:
|
||||
|
||||
```text
|
||||
https://script.google.com/macros/s/xxxxxxxxxxxxxxxx/exec
|
||||
```
|
||||
|
||||
### 6. ทดสอบ endpoint
|
||||
|
||||
เปิด URL ที่ copy มาใน browser ถ้าระบบทำงาน จะเห็น JSON ประมาณ:
|
||||
|
||||
```json
|
||||
{"ok":true,"service":"MoreminiMore lead form"}
|
||||
```
|
||||
|
||||
### 7. เอา URL ไปใส่ในเว็บ
|
||||
|
||||
ตอน implement หน้าเว็บ ให้ตั้งค่า URL นี้เป็น endpoint ของฟอร์ม
|
||||
|
||||
ข้อควรระวัง: Apps Script web app มักไม่เหมาะกับ fetch ที่ต้องอ่าน JSON response ข้ามโดเมนแบบเต็ม ๆ เพราะอาจติด CORS ได้ วิธีที่เหมาะกับ static site คือส่งข้อมูลแบบ simple POST หรือ `fetch(..., { mode: "no-cors" })` แล้วให้หน้าเว็บแสดง success state หลัง request ถูกส่งออกไป
|
||||
|
||||
ตัวอย่าง payload ที่เว็บควรส่ง:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "คุณเอ",
|
||||
"phone": "0800000000",
|
||||
"email": "owner@example.com",
|
||||
"problems": ["ads_not_worth_it", "wrong_leads"],
|
||||
"message": "ยิงแอดอยู่ แต่ยอดขายไม่คุ้ม อยากรู้ว่าควรแก้อะไรก่อน",
|
||||
"pageUrl": "https://moreminimore.com/",
|
||||
"userAgent": "browser user agent"
|
||||
}
|
||||
```
|
||||
|
||||
## Problem Keys ที่ script รองรับ
|
||||
|
||||
| Key | ข้อความ |
|
||||
| --- | --- |
|
||||
| `website_no_leads` | เว็บมีอยู่แล้ว แต่ไม่ค่อยมีลูกค้าทัก |
|
||||
| `ads_not_worth_it` | ยิงแอดอยู่ แต่ยอดขายไม่คุ้ม |
|
||||
| `wrong_leads` | มีคนทักมา แต่ไม่ใช่ลูกค้าที่ใช่ |
|
||||
| `slow_or_error_work` | ทีมงานทำงานเดิม ๆ แต่ทำงานช้า หรือผิดพลาดบ่อย |
|
||||
| `ai_not_sure` | อยากใช้ AI แต่ไม่รู้เริ่มตรงไหน |
|
||||
| `not_sure` | ยังไม่แน่ใจว่าควรแก้อะไรก่อน |
|
||||
|
||||
## วิธีลดโอกาสเมลเข้าขยะ
|
||||
|
||||
Apps Script จะส่งเมลจากบัญชี Google ที่ deploy script ดังนั้นควร:
|
||||
|
||||
- ใช้บัญชี Google Workspace ของบริษัท ถ้ามี
|
||||
- ตั้งค่า SPF/DKIM/DMARC ของโดเมนให้ถูกต้อง
|
||||
- ใช้ subject ปกติ ไม่ spammy เช่น `มีโจทย์ธุรกิจใหม่จากเว็บไซต์ MoreminiMore`
|
||||
- อย่าใช้ email ลูกค้าเป็น `From`
|
||||
- ให้ script ใช้ email ลูกค้าเป็น `Reply-To` แทน
|
||||
- เนื้อหาอีเมลควรเป็นข้อความสะอาด ไม่ใส่คำขายหรือ link เยอะ
|
||||
|
||||
## เวลาแก้ script หลัง deploy
|
||||
|
||||
ถ้าแก้โค้ดหลังจาก deploy แล้ว:
|
||||
|
||||
1. กด `Deploy`
|
||||
2. เลือก `Manage deployments`
|
||||
3. เลือก deployment เดิม
|
||||
4. กด edit
|
||||
5. เลือก version ใหม่ หรือ new version
|
||||
6. กด deploy/update
|
||||
|
||||
ถ้าสร้าง deployment ใหม่ URL อาจเปลี่ยน ต้องเอา URL ใหม่ไปใส่ในเว็บอีกครั้ง
|
||||
|
||||
## Debug เบื้องต้น
|
||||
|
||||
ถ้า submit แล้วไม่เข้า Sheet:
|
||||
|
||||
1. เปิด Apps Script
|
||||
2. ดูเมนู `Executions`
|
||||
3. เปิด execution ล่าสุดเพื่อดู error
|
||||
4. ตรวจว่า deploy เป็น `Who has access: Anyone`
|
||||
5. ตรวจว่าใช้ URL ที่ลงท้าย `/exec` ไม่ใช่ `/dev`
|
||||
|
||||
ถ้าเข้า Sheet แต่ไม่ส่งเมล:
|
||||
|
||||
1. ตรวจสิทธิ์ MailApp ตอน authorize
|
||||
2. ตรวจ `RECIPIENT_EMAIL`
|
||||
3. ตรวจ quota ของ Google account
|
||||
4. ดู error ใน `Executions`
|
||||
290
google-apps-script/lead-form.gs
Normal file
@@ -0,0 +1,290 @@
|
||||
/**
|
||||
* MoreminiMore lead form endpoint.
|
||||
*
|
||||
* Recommended setup:
|
||||
* 1. Create a Google Sheet for leads.
|
||||
* 2. Open Extensions > Apps Script.
|
||||
* 3. Paste this entire file into Code.gs.
|
||||
* 4. Update CONFIG.RECIPIENT_EMAIL.
|
||||
* 5. Deploy as Web app.
|
||||
*/
|
||||
|
||||
const CONFIG = {
|
||||
RECIPIENT_EMAIL: 'contact@moreminimore.com',
|
||||
SHEET_NAME: 'Leads',
|
||||
TIMEZONE: 'Asia/Bangkok',
|
||||
EMAIL_SUBJECT: 'มีโจทย์ธุรกิจใหม่จากเว็บไซต์ MoreminiMore',
|
||||
};
|
||||
|
||||
const PROBLEM_LABELS = {
|
||||
website_no_leads: 'เว็บมีอยู่แล้ว แต่ไม่ค่อยมีลูกค้าทัก',
|
||||
ads_not_worth_it: 'ยิงแอดอยู่ แต่ยอดขายไม่คุ้ม',
|
||||
wrong_leads: 'มีคนทักมา แต่ไม่ใช่ลูกค้าที่ใช่',
|
||||
slow_or_error_work: 'ทีมงานทำงานเดิม ๆ แต่ทำงานช้า หรือผิดพลาดบ่อย',
|
||||
ai_not_sure: 'อยากใช้ AI แต่ไม่รู้เริ่มตรงไหน',
|
||||
not_sure: 'ยังไม่แน่ใจว่าควรแก้อะไรก่อน',
|
||||
};
|
||||
|
||||
function doGet() {
|
||||
return jsonResponse({
|
||||
ok: true,
|
||||
service: 'MoreminiMore lead form',
|
||||
});
|
||||
}
|
||||
|
||||
function doPost(e) {
|
||||
try {
|
||||
const data = parseRequest(e);
|
||||
|
||||
if (isSpam(data)) {
|
||||
return jsonResponse({ ok: true, skipped: true });
|
||||
}
|
||||
|
||||
const lead = normalizeLead(data);
|
||||
const validation = validateLead(lead);
|
||||
|
||||
if (!validation.ok) {
|
||||
return jsonResponse({
|
||||
ok: false,
|
||||
error: validation.error,
|
||||
});
|
||||
}
|
||||
|
||||
const lock = LockService.getScriptLock();
|
||||
lock.waitLock(10000);
|
||||
|
||||
try {
|
||||
appendLead(lead);
|
||||
} finally {
|
||||
lock.releaseLock();
|
||||
}
|
||||
|
||||
sendLeadEmail(lead);
|
||||
|
||||
return jsonResponse({
|
||||
ok: true,
|
||||
message: 'Lead received',
|
||||
diagnosis: buildLightDiagnosis(lead.problems),
|
||||
});
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
return jsonResponse({
|
||||
ok: false,
|
||||
error: 'ระบบรับข้อมูลมีปัญหา กรุณาลองใหม่อีกครั้ง',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function parseRequest(e) {
|
||||
if (!e) return {};
|
||||
|
||||
const contentType = String(e.postData && e.postData.type || '').toLowerCase();
|
||||
const raw = e.postData && e.postData.contents;
|
||||
|
||||
if (raw && contentType.indexOf('application/json') !== -1) {
|
||||
return JSON.parse(raw);
|
||||
}
|
||||
|
||||
if (raw && contentType.indexOf('text/plain') !== -1) {
|
||||
try {
|
||||
return JSON.parse(raw);
|
||||
} catch (error) {
|
||||
return e.parameter || {};
|
||||
}
|
||||
}
|
||||
|
||||
return e.parameter || {};
|
||||
}
|
||||
|
||||
function normalizeLead(data) {
|
||||
const problems = normalizeProblems(data.problems || data.problem || data.problemKeys);
|
||||
|
||||
return {
|
||||
createdAt: Utilities.formatDate(new Date(), CONFIG.TIMEZONE, 'yyyy-MM-dd HH:mm:ss'),
|
||||
name: cleanText(data.name),
|
||||
phone: cleanText(data.phone),
|
||||
email: cleanText(data.email).toLowerCase(),
|
||||
message: cleanText(data.message || data.details || data.note),
|
||||
problems,
|
||||
pageUrl: cleanText(data.pageUrl || data.url),
|
||||
userAgent: cleanText(data.userAgent),
|
||||
};
|
||||
}
|
||||
|
||||
function normalizeProblems(value) {
|
||||
if (!value) return [];
|
||||
|
||||
if (Array.isArray(value)) {
|
||||
return value.map(String).map(cleanText).filter(Boolean);
|
||||
}
|
||||
|
||||
return String(value)
|
||||
.split(',')
|
||||
.map(cleanText)
|
||||
.filter(Boolean);
|
||||
}
|
||||
|
||||
function validateLead(lead) {
|
||||
if (!lead.name) {
|
||||
return { ok: false, error: 'กรุณาใส่ชื่อ' };
|
||||
}
|
||||
|
||||
if (!lead.phone && !lead.email) {
|
||||
return { ok: false, error: 'ใส่เบอร์โทรหรืออีเมลอย่างใดอย่างหนึ่งก็ได้' };
|
||||
}
|
||||
|
||||
if (lead.email && !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(lead.email)) {
|
||||
return { ok: false, error: 'รูปแบบอีเมลไม่ถูกต้อง' };
|
||||
}
|
||||
|
||||
if (lead.message.length > 2000) {
|
||||
return { ok: false, error: 'รายละเอียดโจทย์ยาวเกินไป' };
|
||||
}
|
||||
|
||||
return { ok: true };
|
||||
}
|
||||
|
||||
function appendLead(lead) {
|
||||
const sheet = getLeadSheet();
|
||||
sheet.appendRow([
|
||||
lead.createdAt,
|
||||
lead.name,
|
||||
lead.phone,
|
||||
lead.email,
|
||||
problemLabels(lead.problems).join(', '),
|
||||
lead.message,
|
||||
buildLightDiagnosis(lead.problems),
|
||||
lead.pageUrl,
|
||||
lead.userAgent,
|
||||
]);
|
||||
}
|
||||
|
||||
function getLeadSheet() {
|
||||
const spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
|
||||
let sheet = spreadsheet.getSheetByName(CONFIG.SHEET_NAME);
|
||||
|
||||
if (!sheet) {
|
||||
sheet = spreadsheet.insertSheet(CONFIG.SHEET_NAME);
|
||||
}
|
||||
|
||||
if (sheet.getLastRow() === 0) {
|
||||
sheet.appendRow([
|
||||
'วันที่ส่ง',
|
||||
'ชื่อ',
|
||||
'เบอร์โทร',
|
||||
'อีเมล',
|
||||
'ปัญหาที่เลือก',
|
||||
'รายละเอียด',
|
||||
'แนวทางเริ่มต้น',
|
||||
'Page URL',
|
||||
'User Agent',
|
||||
]);
|
||||
sheet.setFrozenRows(1);
|
||||
}
|
||||
|
||||
return sheet;
|
||||
}
|
||||
|
||||
function sendLeadEmail(lead) {
|
||||
const labels = problemLabels(lead.problems);
|
||||
const diagnosis = buildLightDiagnosis(lead.problems);
|
||||
|
||||
const plainBody = [
|
||||
'มีโจทย์ธุรกิจใหม่จากเว็บไซต์ MoreminiMore',
|
||||
'',
|
||||
`ชื่อ: ${lead.name}`,
|
||||
`เบอร์โทร: ${lead.phone || '-'}`,
|
||||
`อีเมล: ${lead.email || '-'}`,
|
||||
`ปัญหาที่เลือก: ${labels.length ? labels.join(', ') : '-'}`,
|
||||
'',
|
||||
'รายละเอียด:',
|
||||
lead.message || '-',
|
||||
'',
|
||||
`แนวทางเริ่มต้น: ${diagnosis}`,
|
||||
'',
|
||||
`Page URL: ${lead.pageUrl || '-'}`,
|
||||
`เวลาที่ส่ง: ${lead.createdAt}`,
|
||||
].join('\n');
|
||||
|
||||
const htmlBody = `
|
||||
<div style="font-family:Arial,sans-serif;line-height:1.6;color:#17120a">
|
||||
<h2 style="margin:0 0 12px">มีโจทย์ธุรกิจใหม่จากเว็บไซต์ MoreminiMore</h2>
|
||||
<p><strong>ชื่อ:</strong> ${escapeHtml(lead.name)}</p>
|
||||
<p><strong>เบอร์โทร:</strong> ${escapeHtml(lead.phone || '-')}</p>
|
||||
<p><strong>อีเมล:</strong> ${escapeHtml(lead.email || '-')}</p>
|
||||
<p><strong>ปัญหาที่เลือก:</strong> ${escapeHtml(labels.length ? labels.join(', ') : '-')}</p>
|
||||
<p><strong>รายละเอียด:</strong><br>${escapeHtml(lead.message || '-').replace(/\n/g, '<br>')}</p>
|
||||
<p><strong>แนวทางเริ่มต้น:</strong> ${escapeHtml(diagnosis)}</p>
|
||||
<hr>
|
||||
<p style="color:#666;font-size:13px">
|
||||
Page URL: ${escapeHtml(lead.pageUrl || '-')}<br>
|
||||
เวลาที่ส่ง: ${escapeHtml(lead.createdAt)}
|
||||
</p>
|
||||
</div>
|
||||
`;
|
||||
|
||||
const options = {
|
||||
name: 'MoreminiMore Website',
|
||||
htmlBody,
|
||||
};
|
||||
|
||||
if (lead.email) {
|
||||
options.replyTo = lead.email;
|
||||
}
|
||||
|
||||
MailApp.sendEmail(CONFIG.RECIPIENT_EMAIL, CONFIG.EMAIL_SUBJECT, plainBody, options);
|
||||
}
|
||||
|
||||
function buildLightDiagnosis(problemKeys) {
|
||||
const keys = problemKeys || [];
|
||||
|
||||
if (keys.indexOf('ads_not_worth_it') !== -1 || keys.indexOf('wrong_leads') !== -1) {
|
||||
return 'น่าจะเริ่มจากการดูข้อมูลแอด กลุ่มเป้าหมาย และคุณภาพลูกค้าที่ทักเข้ามาก่อน';
|
||||
}
|
||||
|
||||
if (keys.indexOf('website_no_leads') !== -1) {
|
||||
return 'น่าจะเริ่มจากการดูเว็บ เส้นทางลูกค้า และจุดที่ควรชวนให้ติดต่อก่อน';
|
||||
}
|
||||
|
||||
if (keys.indexOf('slow_or_error_work') !== -1) {
|
||||
return 'น่าจะเริ่มจากการดูขั้นตอนทำงานซ้ำ จุดที่ช้า และจุดที่ผิดพลาดบ่อยก่อน';
|
||||
}
|
||||
|
||||
if (keys.indexOf('ai_not_sure') !== -1) {
|
||||
return 'น่าจะเริ่มจากการดูงานจริงของทีมก่อน แล้วค่อยเลือกจุดที่ AI ช่วยได้อย่างเหมาะสม';
|
||||
}
|
||||
|
||||
return 'เราจะเริ่มจากการทำความเข้าใจธุรกิจและข้อมูลที่มีอยู่ก่อน แล้วค่อยแนะนำทางที่คุ้มที่สุด';
|
||||
}
|
||||
|
||||
function problemLabels(problemKeys) {
|
||||
return (problemKeys || []).map(function (key) {
|
||||
return PROBLEM_LABELS[key] || key;
|
||||
});
|
||||
}
|
||||
|
||||
function isSpam(data) {
|
||||
return Boolean(data.website || data.company_url || data.url2);
|
||||
}
|
||||
|
||||
function cleanText(value) {
|
||||
return String(value || '')
|
||||
.replace(/\r/g, '')
|
||||
.trim()
|
||||
.slice(0, 2000);
|
||||
}
|
||||
|
||||
function escapeHtml(value) {
|
||||
return String(value || '')
|
||||
.replace(/&/g, '&')
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>')
|
||||
.replace(/"/g, '"')
|
||||
.replace(/'/g, ''');
|
||||
}
|
||||
|
||||
function jsonResponse(data) {
|
||||
return ContentService
|
||||
.createTextOutput(JSON.stringify(data))
|
||||
.setMimeType(ContentService.MimeType.JSON);
|
||||
}
|
||||
10438
package-lock.json
generated
11
package.json
@@ -1,7 +1,8 @@
|
||||
{
|
||||
"name": "moreminimore-site",
|
||||
"type": "module",
|
||||
"version": "0.0.1",
|
||||
"version": "1.0.0",
|
||||
"private": true,
|
||||
"engines": {
|
||||
"node": ">=22.12.0"
|
||||
},
|
||||
@@ -12,12 +13,6 @@
|
||||
"astro": "astro"
|
||||
},
|
||||
"dependencies": {
|
||||
"@astrojs/mdx": "^5.0.6",
|
||||
"@astrojs/node": "^10.1.1",
|
||||
"@astrojs/react": "^5.0.5",
|
||||
"astro": "^6.2.2",
|
||||
"emdash": "^0.12.0",
|
||||
"react": "^19.2.5",
|
||||
"react-dom": "^19.2.5"
|
||||
"astro": "^6.2.2"
|
||||
}
|
||||
}
|
||||
|
||||
182
public/demos/a-orbital.html
Normal file
@@ -0,0 +1,182 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="th">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>A: Orbital — ระบบดาวเคราะห์</title>
|
||||
<style>
|
||||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
body {
|
||||
font-family: 'Kanit', system-ui, sans-serif;
|
||||
background: #0a0f1a;
|
||||
color: #fff;
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
min-height: 100vh; overflow: hidden;
|
||||
}
|
||||
@import url('https://fonts.googleapis.com/css2?family=Kanit:wght@400;600;800;900&display=swap');
|
||||
|
||||
.demo { position: relative; width: 650px; height: 580px; }
|
||||
|
||||
/* Canvas for orbital rings */
|
||||
canvas#orbitalCanvas {
|
||||
position: absolute; inset: 0; pointer-events: none; z-index: 1;
|
||||
}
|
||||
|
||||
.scene {
|
||||
position: relative; width: 100%; height: 100%;
|
||||
transform-style: preserve-3d;
|
||||
transition: transform 0.2s ease-out;
|
||||
}
|
||||
|
||||
.node {
|
||||
position: absolute; border-radius: 50%;
|
||||
display: flex; flex-direction: column;
|
||||
align-items: center; justify-content: center;
|
||||
text-align: center; backface-visibility: hidden;
|
||||
}
|
||||
|
||||
/* Center Sun */
|
||||
.sun {
|
||||
left: 50%; top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 170px; height: 170px;
|
||||
background: radial-gradient(circle at 40% 35%, #fff7cc, #fed400 40%, #d4a000 100%);
|
||||
box-shadow: 0 0 60px rgba(254,212,0,0.6), 0 0 120px rgba(254,212,0,0.3), 0 0 200px rgba(254,180,0,0.15);
|
||||
z-index: 10; animation: sunPulse 3s ease-in-out infinite;
|
||||
}
|
||||
@keyframes sunPulse {
|
||||
0%, 100% { box-shadow: 0 0 60px rgba(254,212,0,0.6), 0 0 120px rgba(254,212,0,0.3), 0 0 200px rgba(254,180,0,0.15); }
|
||||
50% { box-shadow: 0 0 80px rgba(254,212,0,0.8), 0 0 150px rgba(254,212,0,0.4), 0 0 230px rgba(254,180,0,0.2); }
|
||||
}
|
||||
.sun .label { font-size: 2.8rem; font-weight: 900; color: #3a2e00; }
|
||||
.sun .sub { font-size: 0.75rem; color: #6b5500; margin-top: 4px; font-weight: 600; }
|
||||
|
||||
/* Orbiting planets */
|
||||
.planet {
|
||||
width: 110px; height: 110px;
|
||||
background: rgba(255,255,255,0.06);
|
||||
backdrop-filter: blur(10px);
|
||||
border: 1.5px solid rgba(255,255,255,0.2);
|
||||
box-shadow: 0 8px 32px rgba(0,0,0,0.4), inset 0 1px 0 rgba(255,255,255,0.15);
|
||||
left: 50%; top: 50%;
|
||||
animation: orbit var(--orbit-dur) linear infinite;
|
||||
z-index: 5;
|
||||
}
|
||||
.planet:nth-child(2) { --orbit-dur: 12s; --radius: 230px; --angle: 0deg; --z: -40px; }
|
||||
.planet:nth-child(3) { --orbit-dur: 15s; --radius: 280px; --angle: 120deg; --z: -70px; }
|
||||
.planet:nth-child(4) { --orbit-dur: 18s; --radius: 330px; --angle: 240deg; --z: -100px; }
|
||||
|
||||
@keyframes orbit {
|
||||
0% { transform: translate(-50%, -50%) rotate(0deg) translateX(var(--radius)) rotate(0deg); }
|
||||
100% { transform: translate(-50%, -50%) rotate(360deg) translateX(var(--radius)) rotate(-360deg); }
|
||||
}
|
||||
|
||||
.planet .tag { font-size: 1rem; font-weight: 800; color: #fff; text-transform: uppercase; }
|
||||
.planet .desc { font-size: 0.7rem; color: rgba(255,255,255,0.6); margin-top: 4px; }
|
||||
|
||||
/* Connecting lines (drawn on canvas) */
|
||||
|
||||
.title {
|
||||
position: fixed; top: 24px; left: 50%; transform: translateX(-50%);
|
||||
font-size: 0.8rem; text-transform: uppercase; letter-spacing: 0.2em;
|
||||
color: rgba(255,255,255,0.4); z-index: 100;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<span class="title">A. Orbital — ระบบดาวเคราะห์โคจร</span>
|
||||
<div class="demo">
|
||||
<canvas id="orbitalCanvas"></canvas>
|
||||
<div class="scene" id="scene">
|
||||
<div class="node sun" data-node="center">
|
||||
<span class="label">กำไร</span>
|
||||
<span class="sub">เป้าหมายของทุกธุรกิจ</span>
|
||||
</div>
|
||||
<div class="node planet" data-node="mkt">
|
||||
<span class="tag">Marketing</span>
|
||||
<span class="desc">เพิ่มรายได้</span>
|
||||
</div>
|
||||
<div class="node planet" data-node="ai">
|
||||
<span class="tag">AI</span>
|
||||
<span class="desc">ลดต้นทุนและเวลา</span>
|
||||
</div>
|
||||
<div class="node planet" data-node="biz">
|
||||
<span class="tag">Business<br>Knowledge</span>
|
||||
<span class="desc">ลดความเสี่ยง</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const canvas = document.getElementById('orbitalCanvas');
|
||||
const ctx = canvas.getContext('2d');
|
||||
const scene = document.getElementById('scene');
|
||||
|
||||
function resize() {
|
||||
const rect = canvas.parentElement.getBoundingClientRect();
|
||||
canvas.width = rect.width;
|
||||
canvas.height = rect.height;
|
||||
}
|
||||
resize();
|
||||
window.addEventListener('resize', resize);
|
||||
|
||||
function draw() {
|
||||
const rect = canvas.parentElement.getBoundingClientRect();
|
||||
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||
|
||||
const sun = document.querySelector('[data-node="center"]');
|
||||
const planets = document.querySelectorAll('.planet');
|
||||
if (!sun) return;
|
||||
|
||||
const sunRect = sun.getBoundingClientRect();
|
||||
const sx = sunRect.left + sunRect.width/2 - rect.left;
|
||||
const sy = sunRect.top + sunRect.height/2 - rect.top;
|
||||
|
||||
// Draw orbital rings
|
||||
const sr = 85; // sun radius
|
||||
const radii = [230, 280, 330];
|
||||
radii.forEach((r, i) => {
|
||||
ctx.beginPath();
|
||||
ctx.ellipse(sx, sy, r, r * 0.45, 0, 0, Math.PI * 2);
|
||||
ctx.strokeStyle = `rgba(254,212,0,${0.15 - i * 0.03})`;
|
||||
ctx.lineWidth = 1;
|
||||
ctx.setLineDash([8, 14]);
|
||||
ctx.stroke();
|
||||
ctx.setLineDash([]);
|
||||
});
|
||||
|
||||
// Draw connection lines
|
||||
planets.forEach(p => {
|
||||
const pRect = p.getBoundingClientRect();
|
||||
const px = pRect.left + pRect.width/2 - rect.left;
|
||||
const py = pRect.top + pRect.height/2 - rect.top;
|
||||
|
||||
const dx = px - sx, dy = py - sy;
|
||||
const dist = Math.sqrt(dx*dx + dy*dy);
|
||||
const r = 85;
|
||||
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(sx + (dx/dist)*r, sy + (dy/dist)*r);
|
||||
ctx.lineTo(px - (dx/dist)*55, py - (dy/dist)*55);
|
||||
const grad = ctx.createLinearGradient(sx, sy, px, py);
|
||||
grad.addColorStop(0, 'rgba(254,212,0,0.7)');
|
||||
grad.addColorStop(1, 'rgba(254,212,0,0.15)');
|
||||
ctx.strokeStyle = grad;
|
||||
ctx.lineWidth = 1.5;
|
||||
ctx.stroke();
|
||||
});
|
||||
|
||||
requestAnimationFrame(draw);
|
||||
}
|
||||
|
||||
// Mouse parallax
|
||||
document.addEventListener('mousemove', e => {
|
||||
const x = (e.clientX / window.innerWidth - 0.5) * 8;
|
||||
const y = (e.clientY / window.innerHeight - 0.5) * -8;
|
||||
scene.style.transform = `rotateX(${y}deg) rotateY(${x}deg)`;
|
||||
});
|
||||
|
||||
draw();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
180
public/demos/b-energyflow.html
Normal file
@@ -0,0 +1,180 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="th">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>B: Energy Flow — กระแสพลังงาน</title>
|
||||
<style>
|
||||
@import url('https://fonts.googleapis.com/css2?family=Kanit:wght@400;600;800;900&display=swap');
|
||||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
body {
|
||||
font-family: 'Kanit', system-ui, sans-serif;
|
||||
background: #080d14;
|
||||
color: #fff; overflow: hidden;
|
||||
display: flex; align-items: center; justify-content: center; min-height: 100vh;
|
||||
}
|
||||
.demo { position: relative; width: 650px; height: 580px; }
|
||||
canvas#flowCanvas { position: absolute; inset: 0; z-index: 1; pointer-events: none; }
|
||||
.scene {
|
||||
position: relative; width: 100%; height: 100%;
|
||||
transform-style: preserve-3d;
|
||||
transition: transform 0.3s ease-out;
|
||||
}
|
||||
|
||||
.node {
|
||||
position: absolute;
|
||||
display: flex; flex-direction: column;
|
||||
align-items: center; justify-content: center; text-align: center;
|
||||
}
|
||||
|
||||
/* Core */
|
||||
.core {
|
||||
left: 50%; top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 160px; height: 160px; border-radius: 50%;
|
||||
background: radial-gradient(circle at 35% 30%, #2a1a00, #100800);
|
||||
border: 2px solid rgba(254,212,0,0.8);
|
||||
box-shadow: 0 0 40px rgba(254,212,0,0.3), 0 0 80px rgba(254,180,0,0.1), inset 0 0 40px rgba(254,212,0,0.08);
|
||||
z-index: 10;
|
||||
animation: coreBeat 2s ease-in-out infinite;
|
||||
}
|
||||
@keyframes coreBeat {
|
||||
0%, 100% { box-shadow: 0 0 40px rgba(254,212,0,0.3), 0 0 80px rgba(254,180,0,0.1), inset 0 0 40px rgba(254,212,0,0.08); }
|
||||
50% { box-shadow: 0 0 60px rgba(254,212,0,0.5), 0 0 100px rgba(254,180,0,0.2), inset 0 0 50px rgba(254,212,0,0.12); }
|
||||
}
|
||||
.core .label { font-size: 2.6rem; font-weight: 900; color: #fed400; }
|
||||
.core .sub { font-size: 0.7rem; color: rgba(254,212,0,0.5); margin-top: 4px; font-weight: 600; }
|
||||
|
||||
/* Satellites */
|
||||
.satellite {
|
||||
border-radius: 50%;
|
||||
background: rgba(255,255,255,0.04);
|
||||
backdrop-filter: blur(8px);
|
||||
border: 1px solid rgba(254,212,0,0.25);
|
||||
width: 120px; height: 120px;
|
||||
z-index: 5;
|
||||
left: 50%; top: 50%;
|
||||
}
|
||||
.satellite:nth-child(2) { transform: translate(-50%, -50%) translateY(-230px); animation: float1 4s ease-in-out infinite; }
|
||||
.satellite:nth-child(3) { transform: translate(-50%, -50%) translateX(220px) translateY(10px); animation: float2 4.5s ease-in-out infinite; }
|
||||
.satellite:nth-child(4) { transform: translate(-50%, -50%) translateX(-160px) translateY(190px); animation: float3 5s ease-in-out infinite; }
|
||||
@keyframes float1 { 0%,100%{ transform: translate(-50%,-50%) translateY(-230px); } 50%{ transform: translate(-50%,-50%) translateY(-245px); } }
|
||||
@keyframes float2 { 0%,100%{ transform: translate(-50%,-50%) translateX(220px) translateY(10px); } 50%{ transform: translate(-50%,-50%) translateX(235px) translateY(0px); } }
|
||||
@keyframes float3 { 0%,100%{ transform: translate(-50%,-50%) translateX(-160px) translateY(190px); } 50%{ transform: translate(-50%,-50%) translateX(-175px) translateY(205px); } }
|
||||
|
||||
.satellite .tag { font-size: 0.9rem; font-weight: 800; color: #fff; }
|
||||
.satellite .desc { font-size: 0.65rem; color: rgba(255,255,255,0.5); margin-top: 3px; }
|
||||
|
||||
.title {
|
||||
position: fixed; top: 24px; left: 50%; transform: translateX(-50%);
|
||||
font-size: 0.8rem; text-transform: uppercase; letter-spacing: 0.2em;
|
||||
color: rgba(255,255,255,0.4); z-index: 100;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<span class="title">B. Energy Flow — กระแสพลังงาน พร้อม particles</span>
|
||||
<div class="demo">
|
||||
<canvas id="flowCanvas"></canvas>
|
||||
<div class="scene" id="scene">
|
||||
<div class="node core" data-node="center">
|
||||
<span class="label">กำไร</span>
|
||||
<span class="sub">เป้าหมายของทุกธุรกิจ</span>
|
||||
</div>
|
||||
<div class="node satellite" data-node="mkt">
|
||||
<span class="tag">Marketing</span>
|
||||
<span class="desc">เพิ่มรายได้</span>
|
||||
</div>
|
||||
<div class="node satellite" data-node="ai">
|
||||
<span class="tag">AI</span>
|
||||
<span class="desc">ลดต้นทุนและเวลา</span>
|
||||
</div>
|
||||
<div class="node satellite" data-node="biz">
|
||||
<span class="tag">Business<br>Knowledge</span>
|
||||
<span class="desc">ลดความเสี่ยง</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const canvas = document.getElementById('flowCanvas');
|
||||
const ctx = canvas.getContext('2d');
|
||||
const scene = document.getElementById('scene');
|
||||
|
||||
function resize() {
|
||||
const rect = canvas.parentElement.getBoundingClientRect();
|
||||
canvas.width = rect.width;
|
||||
canvas.height = rect.height;
|
||||
}
|
||||
resize();
|
||||
window.addEventListener('resize', resize);
|
||||
|
||||
// Particle system per connection
|
||||
const connections = [];
|
||||
let t = 0;
|
||||
|
||||
function draw() {
|
||||
t++;
|
||||
const rect = canvas.parentElement.getBoundingClientRect();
|
||||
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||
|
||||
const sun = document.querySelector('[data-node="center"]');
|
||||
const sats = document.querySelectorAll('.satellite');
|
||||
if (!sun) { requestAnimationFrame(draw); return; }
|
||||
|
||||
const sr = sun.getBoundingClientRect();
|
||||
const sx = sr.left + sr.width/2 - rect.left;
|
||||
const sy = sr.top + sr.height/2 - rect.top;
|
||||
|
||||
sats.forEach((sat, i) => {
|
||||
const pr = sat.getBoundingClientRect();
|
||||
const px = pr.left + pr.width/2 - rect.left;
|
||||
const py = pr.top + pr.height/2 - rect.top;
|
||||
|
||||
const dx = px - sx, dy = py - sy;
|
||||
const dist = Math.sqrt(dx*dx + dy*dy);
|
||||
|
||||
// Draw stream line
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(sx + (dx/dist)*80, sy + (dy/dist)*80);
|
||||
ctx.lineTo(px - (dx/dist)*60, py - (dy/dist)*60);
|
||||
const grad = ctx.createLinearGradient(sx, sy, px, py);
|
||||
grad.addColorStop(0, 'rgba(254,212,0,0.6)');
|
||||
grad.addColorStop(0.5, 'rgba(254,212,0,0.3)');
|
||||
grad.addColorStop(1, 'rgba(254,212,0,0.1)');
|
||||
ctx.strokeStyle = grad;
|
||||
ctx.lineWidth = 2;
|
||||
ctx.stroke();
|
||||
|
||||
// Animated particles along the line
|
||||
const count = 12;
|
||||
for (let j = 0; j < count; j++) {
|
||||
const phase = (t * 0.03 + j / count + i * 0.33) % 1;
|
||||
const pp = phase < 0.5 ? phase * 2 : 2 - phase * 2;
|
||||
const x = sx + (dx/dist)*80 + dx * (1 - 80/dist - 60/dist) * phase;
|
||||
const y = sy + (dy/dist)*80 + dy * (1 - 80/dist - 60/dist) * phase;
|
||||
ctx.beginPath();
|
||||
ctx.arc(x, y, 2.5, 0, Math.PI*2);
|
||||
ctx.fillStyle = `rgba(254,230,100,${0.8 * pp})`;
|
||||
ctx.fill();
|
||||
// Glow
|
||||
ctx.beginPath();
|
||||
ctx.arc(x, y, 5, 0, Math.PI*2);
|
||||
ctx.fillStyle = `rgba(254,212,0,${0.25 * pp})`;
|
||||
ctx.fill();
|
||||
}
|
||||
});
|
||||
|
||||
requestAnimationFrame(draw);
|
||||
}
|
||||
|
||||
document.addEventListener('mousemove', e => {
|
||||
const x = (e.clientX / window.innerWidth - 0.5) * 6;
|
||||
const y = (e.clientY / window.innerHeight - 0.5) * -6;
|
||||
scene.style.transform = `rotateX(${y}deg) rotateY(${x}deg)`;
|
||||
});
|
||||
|
||||
draw();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
179
public/demos/c-holographic.html
Normal file
@@ -0,0 +1,179 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="th">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>C: Holographic 3D — Hologram Sci-Fi</title>
|
||||
<style>
|
||||
@import url('https://fonts.googleapis.com/css2?family=Kanit:wght@400;600;800;900&display=swap');
|
||||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
body {
|
||||
font-family: 'Kanit', system-ui, sans-serif;
|
||||
background: #020810;
|
||||
color: #fff; overflow: hidden;
|
||||
display: flex; align-items: center; justify-content: center; min-height: 100vh;
|
||||
}
|
||||
|
||||
.demo { position: relative; width: 700px; height: 600px; }
|
||||
canvas#holoCanvas { position: absolute; inset: 0; z-index: 1; pointer-events: none; }
|
||||
.scene {
|
||||
position: relative; width: 100%; height: 100%;
|
||||
transform-style: preserve-3d; perspective: 1200px;
|
||||
transition: transform 0.2s ease-out;
|
||||
}
|
||||
|
||||
.node {
|
||||
position: absolute;
|
||||
display: flex; flex-direction: column;
|
||||
align-items: center; justify-content: center; text-align: center;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
/* Center hologram */
|
||||
.holo-core {
|
||||
left: 50%; top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 170px; height: 170px;
|
||||
background: radial-gradient(circle at 40% 35%, rgba(0,255,255,0.15), rgba(0,200,255,0.05));
|
||||
border: 2px solid rgba(0,255,255,0.5);
|
||||
box-shadow: 0 0 50px rgba(0,255,255,0.2), 0 0 100px rgba(0,200,255,0.08), inset 0 0 30px rgba(0,255,255,0.05);
|
||||
z-index: 10;
|
||||
animation: holoPulse 2.5s ease-in-out infinite;
|
||||
}
|
||||
@keyframes holoPulse {
|
||||
0%, 100% { border-color: rgba(0,255,255,0.5); box-shadow: 0 0 50px rgba(0,255,255,0.2), 0 0 100px rgba(0,200,255,0.08); }
|
||||
50% { border-color: rgba(0,255,255,0.8); box-shadow: 0 0 70px rgba(0,255,255,0.35), 0 0 120px rgba(0,200,255,0.15); }
|
||||
}
|
||||
.holo-core .label { font-size: 2.8rem; font-weight: 900; color: #0ff; text-shadow: 0 0 20px rgba(0,255,255,0.5); }
|
||||
.holo-core .sub { font-size: 0.7rem; color: rgba(0,255,255,0.5); margin-top: 4px; font-weight: 600; }
|
||||
|
||||
/* Scanline effect */
|
||||
.holo-core::after {
|
||||
content: ''; position: absolute; inset: 0; border-radius: 50%;
|
||||
background: repeating-linear-gradient(0deg, transparent, transparent 2px, rgba(0,255,255,0.03) 2px, rgba(0,255,255,0.03) 4px);
|
||||
pointer-events: none; z-index: 1;
|
||||
}
|
||||
|
||||
/* Satellites - holographic */
|
||||
.holo-sat {
|
||||
width: 115px; height: 115px;
|
||||
background: rgba(0,255,255,0.04);
|
||||
border: 1.5px solid rgba(0,255,255,0.35);
|
||||
box-shadow: 0 0 25px rgba(0,255,255,0.1), inset 0 0 20px rgba(0,255,255,0.04);
|
||||
z-index: 5;
|
||||
left: 50%; top: 50%;
|
||||
}
|
||||
.holo-sat::after {
|
||||
content: ''; position: absolute; inset: 0; border-radius: 50%;
|
||||
background: repeating-linear-gradient(0deg, transparent, transparent 2px, rgba(0,255,255,0.02) 2px, rgba(0,255,255,0.02) 4px);
|
||||
pointer-events: none;
|
||||
}
|
||||
.holo-sat:nth-child(2) { transform: translate(-50%,-50%) translate3d(-220px,-140px,-80px); animation: hfloat1 5s ease-in-out infinite; }
|
||||
.holo-sat:nth-child(3) { transform: translate(-50%,-50%) translate3d(180px,-20px,-30px); animation: hfloat2 6s ease-in-out infinite; }
|
||||
.holo-sat:nth-child(4) { transform: translate(-50%,-50%) translate3d(-100px,210px,-100px); animation: hfloat3 5.5s ease-in-out infinite; }
|
||||
@keyframes hfloat1 { 0%,100%{transform:translate(-50%,-50%) translate3d(-220px,-140px,-80px)} 50%{transform:translate(-50%,-50%) translate3d(-230px,-155px,-100px)} }
|
||||
@keyframes hfloat2 { 0%,100%{transform:translate(-50%,-50%) translate3d(180px,-20px,-30px)} 50%{transform:translate(-50%,-50%) translate3d(195px,-35px,-55px)} }
|
||||
@keyframes hfloat3 { 0%,100%{transform:translate(-50%,-50%) translate3d(-100px,210px,-100px)} 50%{transform:translate(-50%,-50%) translate3d(-115px,225px,-130px)} }
|
||||
|
||||
.holo-sat .tag { font-size: 0.9rem; font-weight: 800; color: #0ff; text-shadow: 0 0 10px rgba(0,255,255,0.4); }
|
||||
.holo-sat .desc { font-size: 0.65rem; color: rgba(0,255,255,0.5); margin-top: 3px; }
|
||||
|
||||
.title {
|
||||
position: fixed; top: 24px; left: 50%; transform: translateX(-50%);
|
||||
font-size: 0.8rem; text-transform: uppercase; letter-spacing: 0.2em;
|
||||
color: rgba(0,255,255,0.4); z-index: 100;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<span class="title">C. Holographic 3D — Hologram Sci-Fi</span>
|
||||
<div class="demo">
|
||||
<canvas id="holoCanvas"></canvas>
|
||||
<div class="scene" id="scene">
|
||||
<div class="node holo-core" data-node="center">
|
||||
<span class="label">กำไร</span>
|
||||
<span class="sub">เป้าหมายของทุกธุรกิจ</span>
|
||||
</div>
|
||||
<div class="node holo-sat" data-node="mkt">
|
||||
<span class="tag">Marketing</span>
|
||||
<span class="desc">เพิ่มรายได้</span>
|
||||
</div>
|
||||
<div class="node holo-sat" data-node="ai">
|
||||
<span class="tag">AI</span>
|
||||
<span class="desc">ลดต้นทุนและเวลา</span>
|
||||
</div>
|
||||
<div class="node holo-sat" data-node="biz">
|
||||
<span class="tag">Business<br>Knowledge</span>
|
||||
<span class="desc">ลดความเสี่ยง</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const canvas = document.getElementById('holoCanvas');
|
||||
const ctx = canvas.getContext('2d');
|
||||
const scene = document.getElementById('scene');
|
||||
|
||||
function resize() {
|
||||
const rect = canvas.parentElement.getBoundingClientRect();
|
||||
canvas.width = rect.width;
|
||||
canvas.height = rect.height;
|
||||
}
|
||||
resize(); window.addEventListener('resize', resize);
|
||||
|
||||
let t = 0;
|
||||
function draw() {
|
||||
t++;
|
||||
const rect = canvas.parentElement.getBoundingClientRect();
|
||||
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||
|
||||
const center = document.querySelector('[data-node="center"]');
|
||||
const sats = document.querySelectorAll('.holo-sat');
|
||||
if (!center) { requestAnimationFrame(draw); return; }
|
||||
|
||||
const cr = center.getBoundingClientRect();
|
||||
const cx = cr.left + cr.width/2 - rect.left;
|
||||
const cy = cr.top + cr.height/2 - rect.top;
|
||||
|
||||
sats.forEach((sat, i) => {
|
||||
const pr = sat.getBoundingClientRect();
|
||||
const px = pr.left + pr.width/2 - rect.left;
|
||||
const py = pr.top + pr.height/2 - rect.top;
|
||||
const dx = px - cx, dy = py - cy;
|
||||
const dist = Math.sqrt(dx*dx + dy*dy);
|
||||
|
||||
// Hologram beam line (dotted)
|
||||
ctx.beginPath();
|
||||
ctx.setLineDash([4, 8]);
|
||||
ctx.lineDashOffset = -t * 2;
|
||||
ctx.moveTo(cx + (dx/dist)*85, cy + (dy/dist)*85);
|
||||
ctx.lineTo(px - (dx/dist)*58, py - (dy/dist)*58);
|
||||
ctx.strokeStyle = 'rgba(0,255,255,0.3)';
|
||||
ctx.lineWidth = 1.5;
|
||||
ctx.stroke();
|
||||
ctx.setLineDash([]);
|
||||
|
||||
// Glow nodes at intervals
|
||||
for (let j = 0; j < 5; j++) {
|
||||
const phase = ((t * 0.02 + j/5 + i*0.33) % 1);
|
||||
const x = cx + (dx/dist)*85 + dx * (1 - 85/dist - 58/dist) * phase;
|
||||
const y = cy + (dy/dist)*85 + dy * (1 - 85/dist - 58/dist) * phase;
|
||||
const alpha = Math.sin(phase * Math.PI);
|
||||
ctx.beginPath();
|
||||
ctx.arc(x, y, 2, 0, Math.PI*2);
|
||||
ctx.fillStyle = `rgba(0,255,255,${0.6 * alpha})`;
|
||||
ctx.fill();
|
||||
}
|
||||
});
|
||||
|
||||
requestAnimationFrame(draw);
|
||||
}
|
||||
|
||||
document.addEventListener('mousemove', e => {
|
||||
scene.style.transform = `rotateX(${(e.clientY/window.innerHeight-0.5)*-8}deg) rotateY(${(e.clientX/window.innerWidth-0.5)*8}deg)`;
|
||||
});
|
||||
|
||||
draw();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
208
public/demos/d-constellation.html
Normal file
@@ -0,0 +1,208 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="th">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>D: Constellation — แผนที่ดาว</title>
|
||||
<style>
|
||||
@import url('https://fonts.googleapis.com/css2?family=Kanit:wght@400;600;800;900&display=swap');
|
||||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
body {
|
||||
font-family: 'Kanit', system-ui, sans-serif;
|
||||
background: radial-gradient(ellipse at center, #0d1520 0%, #040810 100%);
|
||||
color: #fff; overflow: hidden;
|
||||
display: flex; align-items: center; justify-content: center; min-height: 100vh;
|
||||
}
|
||||
|
||||
/* Starfield background */
|
||||
.stars {
|
||||
position: fixed; inset: 0; z-index: 0; pointer-events: none;
|
||||
}
|
||||
|
||||
.demo { position: relative; width: 700px; height: 600px; z-index: 1; }
|
||||
canvas#constCanvas { position: absolute; inset: 0; z-index: 1; pointer-events: none; }
|
||||
.scene {
|
||||
position: relative; width: 100%; height: 100%;
|
||||
transform-style: preserve-3d;
|
||||
transition: transform 0.3s ease-out;
|
||||
}
|
||||
|
||||
.node {
|
||||
position: absolute;
|
||||
display: flex; flex-direction: column;
|
||||
align-items: center; justify-content: center; text-align: center;
|
||||
}
|
||||
|
||||
/* Polaris - main star */
|
||||
.star-main {
|
||||
left: 50%; top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 150px; height: 150px; border-radius: 50%;
|
||||
background: radial-gradient(circle at 38% 35%, rgba(255,255,255,0.25), rgba(254,212,0,0.15) 50%, transparent 100%);
|
||||
z-index: 10;
|
||||
}
|
||||
.star-main .glow {
|
||||
position: absolute; inset: -30px; border-radius: 50%;
|
||||
background: radial-gradient(circle, rgba(254,212,0,0.08), transparent 70%);
|
||||
animation: starGlow 3s ease-in-out infinite;
|
||||
}
|
||||
@keyframes starGlow {
|
||||
0%, 100% { transform: scale(1); opacity: 0.5; }
|
||||
50% { transform: scale(1.15); opacity: 0.8; }
|
||||
}
|
||||
.star-main .label { font-size: 2.6rem; font-weight: 900; color: #fed400; text-shadow: 0 0 30px rgba(254,212,0,0.6); position: relative; z-index: 1; }
|
||||
.star-main .sub { font-size: 0.7rem; color: rgba(254,212,0,0.5); margin-top: 4px; font-weight: 600; position: relative; z-index: 1; }
|
||||
|
||||
/* Constellation stars */
|
||||
.c-star {
|
||||
width: 70px; height: 70px; border-radius: 50%;
|
||||
background: radial-gradient(circle at 40% 35%, rgba(255,255,255,0.15), transparent);
|
||||
z-index: 5;
|
||||
left: 50%; top: 50%;
|
||||
}
|
||||
/* Star twinkle */
|
||||
.c-star::before {
|
||||
content: ''; position: absolute; inset: -15px; border-radius: 50%;
|
||||
background: radial-gradient(circle, rgba(254,240,200,0.1), transparent 70%);
|
||||
animation: twinkle 4s ease-in-out infinite;
|
||||
}
|
||||
@keyframes twinkle {
|
||||
0%, 100% { opacity: 0.3; transform: scale(0.8); }
|
||||
50% { opacity: 0.7; transform: scale(1.15); }
|
||||
}
|
||||
|
||||
.c-star:nth-child(2)::before { animation-delay: 0s; }
|
||||
.c-star:nth-child(3)::before { animation-delay: 1.2s; }
|
||||
.c-star:nth-child(4)::before { animation-delay: 2.5s; }
|
||||
|
||||
/* Star points (4-point cross) */
|
||||
.c-star::after {
|
||||
content: ''; position: absolute; inset: -8px; border-radius: 50%;
|
||||
box-shadow:
|
||||
0 -25px 0 -8px rgba(254,240,200,0.3),
|
||||
0 25px 0 -8px rgba(254,240,200,0.3),
|
||||
-25px 0 0 -8px rgba(254,240,200,0.3),
|
||||
25px 0 0 -8px rgba(254,240,200,0.3);
|
||||
animation: starRotate 10s linear infinite;
|
||||
}
|
||||
@keyframes starRotate { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }
|
||||
|
||||
.c-star:nth-child(2) { transform: translate(-50%,-50%) translate3d(-220px,-160px,-60px); }
|
||||
.c-star:nth-child(3) { transform: translate(-50%,-50%) translate3d(190px,-30px,-30px); }
|
||||
.c-star:nth-child(4) { transform: translate(-50%,-50%) translate3d(-120px,200px,-70px); }
|
||||
|
||||
.c-star .tag { font-size: 0.8rem; font-weight: 800; color: #fff; position: relative; z-index: 1; text-shadow: 0 0 15px rgba(255,255,255,0.4); }
|
||||
.c-star .desc { font-size: 0.6rem; color: rgba(255,255,255,0.5); margin-top: 2px; position: relative; z-index: 1; }
|
||||
|
||||
.title {
|
||||
position: fixed; top: 24px; left: 50%; transform: translateX(-50%);
|
||||
font-size: 0.8rem; text-transform: uppercase; letter-spacing: 0.2em;
|
||||
color: rgba(255,255,255,0.4); z-index: 100;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<span class="title">D. Constellation — แผนที่ดาว</span>
|
||||
|
||||
<!-- Starfield -->
|
||||
<svg class="stars" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<radialGradient id="s"><stop offset="0%" stop-color="#fff" stop-opacity="0.8"/><stop offset="100%" stop-color="#fff" stop-opacity="0"/></radialGradient>
|
||||
</defs>
|
||||
<circle cx="8%" cy="12%" r="1.5" fill="#fff" opacity="0.6"/><circle cx="15%" cy="8%" r="1" fill="#fff" opacity="0.3"/>
|
||||
<circle cx="22%" cy="18%" r="0.8" fill="#fff" opacity="0.5"/><circle cx="78%" cy="10%" r="1.2" fill="#fff" opacity="0.4"/>
|
||||
<circle cx="85%" cy="22%" r="1" fill="#fff" opacity="0.3"/><circle cx="92%" cy="8%" r="0.6" fill="#fff" opacity="0.7"/>
|
||||
<circle cx="6%" cy="85%" r="1" fill="#fff" opacity="0.4"/><circle cx="14%" cy="92%" r="0.8" fill="#fff" opacity="0.5"/>
|
||||
<circle cx="88%" cy="88%" r="1.3" fill="#fff" opacity="0.35"/><circle cx="95%" cy="78%" r="0.7" fill="#fff" opacity="0.6"/>
|
||||
<circle cx="42%" cy="5%" r="0.9" fill="#fff" opacity="0.45"/><circle cx="55%" cy="3%" r="0.5" fill="#fff" opacity="0.55"/>
|
||||
<circle cx="65%" cy="92%" r="1.1" fill="#fff" opacity="0.3"/><circle cx="35%" cy="95%" r="0.7" fill="#fff" opacity="0.5"/>
|
||||
</svg>
|
||||
|
||||
<div class="demo">
|
||||
<canvas id="constCanvas"></canvas>
|
||||
<div class="scene" id="scene">
|
||||
<div class="node star-main" data-node="center">
|
||||
<div class="glow"></div>
|
||||
<span class="label">กำไร</span>
|
||||
<span class="sub">เป้าหมายของทุกธุรกิจ</span>
|
||||
</div>
|
||||
<div class="node c-star" data-node="mkt">
|
||||
<span class="tag">Marketing</span>
|
||||
<span class="desc">เพิ่มรายได้</span>
|
||||
</div>
|
||||
<div class="node c-star" data-node="ai">
|
||||
<span class="tag">AI</span>
|
||||
<span class="desc">ลดต้นทุน</span>
|
||||
</div>
|
||||
<div class="node c-star" data-node="biz">
|
||||
<span class="tag">Business Knowledge</span>
|
||||
<span class="desc">ลดความเสี่ยง</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const canvas = document.getElementById('constCanvas');
|
||||
const ctx = canvas.getContext('2d');
|
||||
const scene = document.getElementById('scene');
|
||||
|
||||
function resize() {
|
||||
const rect = canvas.parentElement.getBoundingClientRect();
|
||||
canvas.width = rect.width;
|
||||
canvas.height = rect.height;
|
||||
}
|
||||
resize(); window.addEventListener('resize', resize);
|
||||
|
||||
function draw() {
|
||||
const rect = canvas.parentElement.getBoundingClientRect();
|
||||
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||
|
||||
const center = document.querySelector('[data-node="center"]');
|
||||
const stars = document.querySelectorAll('.c-star');
|
||||
if (!center) { requestAnimationFrame(draw); return; }
|
||||
|
||||
const cr = center.getBoundingClientRect();
|
||||
const cx = cr.left + cr.width/2 - rect.left;
|
||||
const cy = cr.top + cr.height/2 - rect.top;
|
||||
|
||||
// Draw constellation lines (thin, elegant)
|
||||
stars.forEach((star, i) => {
|
||||
const pr = star.getBoundingClientRect();
|
||||
const px = pr.left + pr.width/2 - rect.left;
|
||||
const py = pr.top + pr.height/2 - rect.top;
|
||||
const dx = px - cx, dy = py - cy;
|
||||
const dist = Math.sqrt(dx*dx + dy*dy);
|
||||
|
||||
// Constellation line
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(cx + (dx/dist)*75, cy + (dy/dist)*75);
|
||||
ctx.lineTo(px - (dx/dist)*35, py - (dy/dist)*35);
|
||||
ctx.strokeStyle = 'rgba(254,240,200,0.25)';
|
||||
ctx.lineWidth = 1;
|
||||
ctx.setLineDash([2, 6]);
|
||||
ctx.stroke();
|
||||
ctx.setLineDash([]);
|
||||
|
||||
// Tiny connecting stars along line
|
||||
for (let j = 0; j < 3; j++) {
|
||||
const p = 0.25 + j * 0.25;
|
||||
const sx = cx + (dx/dist)*75 + dx * (1 - 75/dist - 35/dist) * p;
|
||||
const sy = cy + (dy/dist)*75 + dy * (1 - 75/dist - 35/dist) * p;
|
||||
ctx.beginPath();
|
||||
ctx.arc(sx, sy, 1.2, 0, Math.PI*2);
|
||||
ctx.fillStyle = 'rgba(255,255,255,0.3)';
|
||||
ctx.fill();
|
||||
}
|
||||
});
|
||||
|
||||
requestAnimationFrame(draw);
|
||||
}
|
||||
|
||||
document.addEventListener('mousemove', e => {
|
||||
scene.style.transform = `rotateX(${(e.clientY/window.innerHeight-0.5)*-5}deg) rotateY(${(e.clientX/window.innerWidth-0.5)*5}deg)`;
|
||||
});
|
||||
|
||||
draw();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
197
public/demos/e-magnetic.html
Normal file
@@ -0,0 +1,197 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="th">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>E: Magnetic Field — สนามแม่เหล็ก</title>
|
||||
<style>
|
||||
@import url('https://fonts.googleapis.com/css2?family=Kanit:wght@400;600;800;900&display=swap');
|
||||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
body {
|
||||
font-family: 'Kanit', system-ui, sans-serif;
|
||||
background: #060a12;
|
||||
color: #fff; overflow: hidden;
|
||||
display: flex; align-items: center; justify-content: center; min-height: 100vh;
|
||||
}
|
||||
|
||||
.demo { position: relative; width: 700px; height: 600px; }
|
||||
canvas#magCanvas { position: absolute; inset: 0; z-index: 1; pointer-events: none; }
|
||||
.scene {
|
||||
position: relative; width: 100%; height: 100%;
|
||||
transform-style: preserve-3d;
|
||||
transition: transform 0.3s ease-out;
|
||||
}
|
||||
|
||||
.node {
|
||||
position: absolute;
|
||||
display: flex; flex-direction: column;
|
||||
align-items: center; justify-content: center; text-align: center;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
/* Magnet core */
|
||||
.magnet {
|
||||
left: 50%; top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 170px; height: 170px;
|
||||
background: radial-gradient(circle at 40% 35%, #3a2000, #0d0500);
|
||||
border: 3px solid #fed400;
|
||||
box-shadow: 0 0 0 12px rgba(254,212,0,0.1), 0 0 60px rgba(254,212,0,0.3), 0 0 140px rgba(254,180,0,0.1);
|
||||
z-index: 10;
|
||||
animation: magnetPulse 2s ease-in-out infinite;
|
||||
}
|
||||
@keyframes magnetPulse {
|
||||
0%, 100% { box-shadow: 0 0 0 12px rgba(254,212,0,0.1), 0 0 60px rgba(254,212,0,0.3), 0 0 140px rgba(254,180,0,0.1); }
|
||||
50% { box-shadow: 0 0 0 18px rgba(254,212,0,0.15), 0 0 80px rgba(254,212,0,0.4), 0 0 160px rgba(254,180,0,0.15); }
|
||||
}
|
||||
.magnet .label { font-size: 2.6rem; font-weight: 900; color: #fed400; }
|
||||
.magnet .sub { font-size: 0.7rem; color: rgba(254,212,0,0.5); margin-top: 4px; font-weight: 600; }
|
||||
|
||||
/* Attracted nodes */
|
||||
.attract {
|
||||
width: 105px; height: 105px;
|
||||
background: rgba(254,212,0,0.04);
|
||||
border: 1.5px solid rgba(254,212,0,0.3);
|
||||
box-shadow: 0 0 20px rgba(254,212,0,0.08);
|
||||
z-index: 5;
|
||||
left: 50%; top: 50%;
|
||||
animation: attract 3s ease-in-out infinite alternate;
|
||||
}
|
||||
.attract:nth-child(2) {
|
||||
transform: translate(-50%,-50%) translate3d(-200px,-150px,-60px);
|
||||
animation-name: attract1;
|
||||
}
|
||||
.attract:nth-child(3) {
|
||||
transform: translate(-50%,-50%) translate3d(170px,-20px,-25px);
|
||||
animation-name: attract2;
|
||||
}
|
||||
.attract:nth-child(4) {
|
||||
transform: translate(-50%,-50%) translate3d(-100px,190px,-70px);
|
||||
animation-name: attract3;
|
||||
}
|
||||
|
||||
@keyframes attract1 {
|
||||
0% { transform: translate(-50%,-50%) translate3d(-220px,-160px,-80px); }
|
||||
100% { transform: translate(-50%,-50%) translate3d(-185px,-140px,-50px); }
|
||||
}
|
||||
@keyframes attract2 {
|
||||
0% { transform: translate(-50%,-50%) translate3d(185px,-25px,-35px); }
|
||||
100% { transform: translate(-50%,-50%) translate3d(155px,-15px,-20px); }
|
||||
}
|
||||
@keyframes attract3 {
|
||||
0% { transform: translate(-50%,-50%) translate3d(-120px,210px,-90px); }
|
||||
100% { transform: translate(-50%,-50%) translate3d(-90px,180px,-60px); }
|
||||
}
|
||||
|
||||
.attract .tag { font-size: 0.9rem; font-weight: 800; color: #fff; }
|
||||
.attract .desc { font-size: 0.65rem; color: rgba(255,255,255,0.5); margin-top: 3px; }
|
||||
|
||||
.title {
|
||||
position: fixed; top: 24px; left: 50%; transform: translateX(-50%);
|
||||
font-size: 0.8rem; text-transform: uppercase; letter-spacing: 0.2em;
|
||||
color: rgba(255,255,255,0.4); z-index: 100;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<span class="title">E. Magnetic Field — สนามแม่เหล็กดึงดูด</span>
|
||||
<div class="demo">
|
||||
<canvas id="magCanvas"></canvas>
|
||||
<div class="scene" id="scene">
|
||||
<div class="node magnet" data-node="center">
|
||||
<span class="label">กำไร</span>
|
||||
<span class="sub">เป้าหมายของทุกธุรกิจ</span>
|
||||
</div>
|
||||
<div class="node attract" data-node="mkt">
|
||||
<span class="tag">Marketing</span>
|
||||
<span class="desc">เพิ่มรายได้</span>
|
||||
</div>
|
||||
<div class="node attract" data-node="ai">
|
||||
<span class="tag">AI</span>
|
||||
<span class="desc">ลดต้นทุนและเวลา</span>
|
||||
</div>
|
||||
<div class="node attract" data-node="biz">
|
||||
<span class="tag">Business<br>Knowledge</span>
|
||||
<span class="desc">ลดความเสี่ยง</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const canvas = document.getElementById('magCanvas');
|
||||
const ctx = canvas.getContext('2d');
|
||||
const scene = document.getElementById('scene');
|
||||
|
||||
function resize() {
|
||||
const rect = canvas.parentElement.getBoundingClientRect();
|
||||
canvas.width = rect.width;
|
||||
canvas.height = rect.height;
|
||||
}
|
||||
resize(); window.addEventListener('resize', resize);
|
||||
|
||||
let t = 0;
|
||||
function draw() {
|
||||
t++;
|
||||
const rect = canvas.parentElement.getBoundingClientRect();
|
||||
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||
|
||||
const center = document.querySelector('[data-node="center"]');
|
||||
const nodes = document.querySelectorAll('.attract');
|
||||
if (!center) { requestAnimationFrame(draw); return; }
|
||||
|
||||
const cr = center.getBoundingClientRect();
|
||||
const cx = cr.left + cr.width/2 - rect.left;
|
||||
const cy = cr.top + cr.height/2 - rect.top;
|
||||
|
||||
// Magnetic field lines (ripple waves)
|
||||
for (let r = 0; r < 4; r++) {
|
||||
const radius = 95 + r * 30 + (t * 0.02) % 30;
|
||||
const alpha = Math.max(0, 0.25 - r * 0.06 - ((t * 0.02) % 30) / 120);
|
||||
ctx.beginPath();
|
||||
ctx.arc(cx, cy, radius, 0, Math.PI*2);
|
||||
ctx.strokeStyle = `rgba(254,212,0,${alpha})`;
|
||||
ctx.lineWidth = 1;
|
||||
ctx.stroke();
|
||||
}
|
||||
|
||||
// Connection lines with magnetic field arcs
|
||||
nodes.forEach((node, i) => {
|
||||
const pr = node.getBoundingClientRect();
|
||||
const px = pr.left + pr.width/2 - rect.left;
|
||||
const py = pr.top + pr.height/2 - rect.top;
|
||||
const dx = px - cx, dy = py - cy;
|
||||
const dist = Math.sqrt(dx*dx + dy*dy);
|
||||
|
||||
// Main connection
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(cx + (dx/dist)*85, cy + (dy/dist)*85);
|
||||
ctx.lineTo(px - (dx/dist)*53, py - (dy/dist)*53);
|
||||
ctx.strokeStyle = `rgba(254,212,0,0.4)`;
|
||||
ctx.lineWidth = 2;
|
||||
ctx.stroke();
|
||||
|
||||
// Field curve arcs on both sides
|
||||
for (let side = -1; side <= 1; side += 2) {
|
||||
const offset = side * 15;
|
||||
const midX = cx + dx * 0.5 + (-dy/dist) * offset;
|
||||
const midY = cy + dy * 0.5 + (dx/dist) * offset;
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(cx + (dx/dist)*85, cy + (dy/dist)*85);
|
||||
ctx.quadraticCurveTo(midX, midY, px - (dx/dist)*53, py - (dy/dist)*53);
|
||||
ctx.strokeStyle = `rgba(254,212,0,0.1)`;
|
||||
ctx.lineWidth = 1;
|
||||
ctx.stroke();
|
||||
}
|
||||
});
|
||||
|
||||
requestAnimationFrame(draw);
|
||||
}
|
||||
|
||||
document.addEventListener('mousemove', e => {
|
||||
scene.style.transform = `rotateX(${(e.clientY/window.innerHeight-0.5)*-6}deg) rotateY(${(e.clientX/window.innerWidth-0.5)*6}deg)`;
|
||||
});
|
||||
|
||||
draw();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
75
public/demos/index.html
Normal file
@@ -0,0 +1,75 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="th">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Hero Design Demos</title>
|
||||
<style>
|
||||
@import url('https://fonts.googleapis.com/css2?family=Kanit:wght@400;600;800;900&display=swap');
|
||||
* { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
body {
|
||||
font-family: 'Kanit', system-ui, sans-serif;
|
||||
background: #0d1117;
|
||||
color: #fff;
|
||||
min-height: 100vh;
|
||||
padding: 48px 24px;
|
||||
}
|
||||
h1 { font-size: 2rem; text-align: center; margin-bottom: 8px; }
|
||||
h1 span { color: #fed400; }
|
||||
.sub { text-align: center; color: rgba(255,255,255,0.5); margin-bottom: 40px; font-size: 1rem; }
|
||||
.grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 20px; max-width: 1000px; margin: 0 auto; }
|
||||
.card {
|
||||
background: rgba(255,255,255,0.04);
|
||||
border: 1px solid rgba(255,255,255,0.1);
|
||||
border-radius: 16px;
|
||||
padding: 32px 24px;
|
||||
text-decoration: none;
|
||||
color: #fff;
|
||||
transition: all 0.3s ease;
|
||||
display: flex; flex-direction: column; gap: 12px;
|
||||
}
|
||||
.card:hover { background: rgba(254,212,0,0.06); border-color: rgba(254,212,0,0.3); transform: translateY(-2px); }
|
||||
.card .emoji { font-size: 3rem; }
|
||||
.card .name { font-size: 1.3rem; font-weight: 800; }
|
||||
.card .name span { color: #fed400; }
|
||||
.card .desc { font-size: 0.82rem; color: rgba(255,255,255,0.5); line-height: 1.5; }
|
||||
.card .tag { display: inline-block; font-size: 0.65rem; text-transform: uppercase; letter-spacing: 0.15em; color: rgba(254,212,0,0.6); border: 1px solid rgba(254,212,0,0.2); border-radius: 20px; padding: 4px 10px; width: fit-content; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Hero Section — <span>5 Design Demos</span></h1>
|
||||
<p class="sub">เลือกดูแต่ละแนวคิดเพื่อเปรียบเทียบ</p>
|
||||
<div class="grid">
|
||||
<a href="a-orbital.html" class="card">
|
||||
<div class="emoji">🌌</div>
|
||||
<div class="name">A. <span>Orbital</span></div>
|
||||
<div class="tag">ระบบดาวเคราะห์โคจร</div>
|
||||
<div class="desc">กำไรเป็นดวงอาทิตย์เรืองแสง 3 ป้ายโคจรรอบด้วยวงแหวน orbital พร้อมหมุนอัตโนมัติ</div>
|
||||
</a>
|
||||
<a href="b-energyflow.html" class="card">
|
||||
<div class="emoji">⚡</div>
|
||||
<div class="name">B. <span>Energy Flow</span></div>
|
||||
<div class="tag">กระแสพลังงาน</div>
|
||||
<div class="desc">Particle วิ่งตามเส้นเชื่อมสีทอง เหมือนพลังงาน/ข้อมูลไหลเข้าสู่กำไร ดูมีชีวิตชีวา</div>
|
||||
</a>
|
||||
<a href="c-holographic.html" class="card">
|
||||
<div class="emoji">🌀</div>
|
||||
<div class="name">C. <span>Holographic 3D</span></div>
|
||||
<div class="tag">Hologram Sci-Fi</div>
|
||||
<div class="desc">โทน Cyan เรืองแสง พร้อม scanline และ beam เชื่อมต่อ ดูล้ำสมัย ดูแพง</div>
|
||||
</a>
|
||||
<a href="d-constellation.html" class="card">
|
||||
<div class="emoji">✨</div>
|
||||
<div class="name">D. <span>Constellation</span></div>
|
||||
<div class="tag">แผนที่ดาว</div>
|
||||
<div class="desc">โหนดเป็นดาวระยิบระยับ เส้นเชื่อมแบบกลุ่มดาว พื้นหลังมีดาวกระจาย ดูลึกลับสง่า</div>
|
||||
</a>
|
||||
<a href="e-magnetic.html" class="card">
|
||||
<div class="emoji">🧲</div>
|
||||
<div class="name">E. <span>Magnetic Field</span></div>
|
||||
<div class="tag">สนามแม่เหล็ก</div>
|
||||
<div class="desc">กำไรเป็นแม่เหล็กทรงพลัง มี ripple wave + field curve สื่อถึงการดึงดูดทุกอย่างสู่กำไร</div>
|
||||
</a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
Before Width: | Height: | Size: 655 B |
@@ -1,9 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 128 128">
|
||||
<path d="M50.4 78.5a75.1 75.1 0 0 0-28.5 6.9l24.2-65.7c.7-2 1.9-3.2 3.4-3.2h29c1.5 0 2.7 1.2 3.4 3.2l24.2 65.7s-11.6-7-28.5-7L67 45.5c-.4-1.7-1.6-2.8-2.9-2.8-1.3 0-2.5 1.1-2.9 2.7L50.4 78.5Zm-1.1 28.2Zm-4.2-20.2c-2 6.6-.6 15.8 4.2 20.2a17.5 17.5 0 0 1 .2-.7 5.5 5.5 0 0 1 5.7-4.5c2.8.1 4.3 1.5 4.7 4.7.2 1.1.2 2.3.2 3.5v.4c0 2.7.7 5.2 2.2 7.4a13 13 0 0 0 5.7 4.9v-.3l-.2-.3c-1.8-5.6-.5-9.5 4.4-12.8l1.5-1a73 73 0 0 0 3.2-2.2 16 16 0 0 0 6.8-11.4c.3-2 .1-4-.6-6l-.8.6-1.6 1a37 37 0 0 1-22.4 2.7c-5-.7-9.7-2-13.2-6.2Z" />
|
||||
<style>
|
||||
path { fill: #000; }
|
||||
@media (prefers-color-scheme: dark) {
|
||||
path { fill: #FFF; }
|
||||
}
|
||||
</style>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 749 B |
@@ -1 +0,0 @@
|
||||
<svg fill="#0866FF" role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Facebook</title><path d="M9.101 23.691v-7.98H6.627v-3.667h2.474v-1.58c0-4.085 1.848-5.978 5.858-5.978.401 0 .955.042 1.468.103a8.68 8.68 0 0 1 1.141.195v3.325a8.623 8.623 0 0 0-.653-.036 26.805 26.805 0 0 0-.733-.009c-.707 0-1.259.096-1.675.309a1.686 1.686 0 0 0-.679.622c-.258.42-.374.995-.374 1.752v1.297h3.919l-.386 2.103-.287 1.564h-3.246v8.245C19.396 23.238 24 18.179 24 12.044c0-6.627-5.373-12-12-12s-12 5.373-12 12c0 5.628 3.874 10.35 9.101 11.647Z"/></svg>
|
||||
|
Before Width: | Height: | Size: 558 B |
@@ -1,10 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="100%" height="100%" viewBox="0 0 36 36" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
|
||||
<g transform="matrix(1,0,0,1,-6,-6)">
|
||||
<path d="M12.5,42L35.5,42C39.09,42 42,39.09 42,35.5L42,12.5C42,8.91 39.09,6 35.5,6L12.5,6C8.91,6 6,8.91 6,12.5L6,35.5C6,39.09 8.91,42 12.5,42Z" style="fill:rgb(0,195,0);fill-rule:nonzero;"/>
|
||||
</g>
|
||||
<g transform="matrix(1,0,0,1,-6,-6)">
|
||||
<path d="M37.113,22.417C37.113,16.552 31.233,11.78 24.006,11.78C16.779,11.78 10.898,16.552 10.898,22.417C10.898,27.675 15.561,32.079 21.86,32.912C22.287,33.004 22.868,33.194 23.015,33.558C23.147,33.889 23.101,34.408 23.057,34.743C23.057,34.743 22.904,35.668 22.87,35.865C22.813,36.196 22.607,37.161 24.005,36.572C25.404,35.983 31.553,32.127 34.303,28.961L34.302,28.961C36.203,26.879 37.113,24.764 37.113,22.417ZM18.875,25.907L16.271,25.907C15.892,25.907 15.584,25.599 15.584,25.219L15.584,20.01C15.584,19.631 15.892,19.323 16.271,19.323C16.65,19.323 16.958,19.631 16.958,20.01L16.958,24.531L18.875,24.531C19.254,24.531 19.562,24.839 19.562,25.218C19.562,25.598 19.254,25.907 18.875,25.907ZM21.568,25.219C21.568,25.598 21.26,25.907 20.881,25.907C20.502,25.907 20.194,25.599 20.194,25.219L20.194,20.01C20.194,19.631 20.502,19.323 20.881,19.323C21.26,19.323 21.568,19.631 21.568,20.01L21.568,25.219ZM27.838,25.219C27.838,25.516 27.65,25.778 27.368,25.871C27.297,25.895 27.223,25.907 27.15,25.907C26.935,25.907 26.73,25.804 26.601,25.632L23.932,21.997L23.932,25.219C23.932,25.598 23.624,25.907 23.244,25.907C22.865,25.907 22.556,25.599 22.556,25.219L22.556,20.01C22.556,19.714 22.745,19.452 23.026,19.358C23.097,19.334 23.17,19.323 23.244,19.323C23.458,19.323 23.664,19.426 23.793,19.598L26.463,23.233L26.463,20.01C26.463,19.631 26.772,19.323 27.151,19.323C27.53,19.323 27.838,19.631 27.838,20.01L27.838,25.219ZM32.052,21.927C32.431,21.927 32.74,22.235 32.74,22.615C32.74,22.994 32.432,23.302 32.052,23.302L30.135,23.302L30.135,24.532L32.052,24.532C32.431,24.532 32.74,24.84 32.74,25.219C32.74,25.598 32.431,25.907 32.052,25.907L29.448,25.907C29.07,25.907 28.761,25.599 28.761,25.219L28.761,20.011C28.761,19.632 29.069,19.324 29.448,19.324L32.052,19.324C32.431,19.324 32.74,19.632 32.74,20.011C32.74,20.39 32.432,20.698 32.052,20.698L30.135,20.698L30.135,21.928L32.052,21.928L32.052,21.927Z" style="fill:white;fill-rule:nonzero;"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 2.6 KiB |
@@ -1 +0,0 @@
|
||||
<svg role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48"><path fill="#00c300" d="M12.5,42h23c3.59,0,6.5-2.91,6.5-6.5v-23C42,8.91,39.09,6,35.5,6h-23C8.91,6,6,8.91,6,12.5v23C6,39.09,8.91,42,12.5,42z"/><path fill="#fff" d="M37.113,22.417c0-5.865-5.88-10.637-13.107-10.637s-13.108,4.772-13.108,10.637c0,5.258,4.663,9.662,10.962,10.495c0.427,0.092,1.008,0.282,1.155,0.646c0.132,0.331,0.086,0.85,0.042,1.185c0,0-0.153,0.925-0.187,1.122c-0.057,0.331-0.263,1.296,1.135,0.707c1.399-0.589,7.548-4.445,10.298-7.611h-0.001C36.203,26.879,37.113,24.764,37.113,22.417z M18.875,25.907h-2.604c-0.379,0-0.687-0.308-0.687-0.688V20.01c0-0.379,0.308-0.687,0.687-0.687c0.379,0,0.687,0.308,0.687,0.687v4.521h1.917c0.379,0,0.687,0.308,0.687,0.687C19.562,25.598,19.254,25.907,18.875,25.907z M21.568,25.219c0,0.379-0.308,0.688-0.687,0.688s-0.687-0.308-0.687-0.688V20.01c0-0.379,0.308-0.687,0.687-0.687s0.687,0.308,0.687,0.687V25.219z M27.838,25.219c0,0.297-0.188,0.559-0.47,0.652c-0.071,0.024-0.145,0.036-0.218,0.036c-0.215,0-0.42-0.103-0.549-0.275l-2.669-3.635v3.222c0,0.379-0.308,0.688-0.688,0.688c-0.379,0-0.688-0.308-0.688-0.688V20.01c0-0.296,0.189-0.558,0.47-0.652c0.071-0.024,0.144-0.035,0.218-0.035c0.214,0,0.42,0.103,0.549,0.275l2.67,3.635V20.01c0-0.379,0.309-0.687,0.688-0.687c0.379,0,0.687,0.308,0.687,0.687V25.219z M32.052,21.927c0.379,0,0.688,0.308,0.688,0.688c0,0.379-0.308,0.687-0.688,0.687h-1.917v1.23h1.917c0.379,0,0.688,0.308,0.688,0.687c0,0.379-0.309,0.688-0.688,0.688h-2.604c-0.378,0-0.687-0.308-0.687-0.688v-2.603c0-0.001,0-0.001,0-0.001c0,0,0-0.001,0-0.001v-2.601c0-0.001,0-0.001,0-0.002c0-0.379,0.308-0.687,0.687-0.687h2.604c0.379,0,0.688,0.308,0.688,0.687s-0.308,0.687-0.688,0.687h-1.917v1.23H32.052z"/></svg>
|
||||
|
Before Width: | Height: | Size: 1.7 KiB |
@@ -1 +0,0 @@
|
||||
<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" fill="#0A66C2"><title>LinkedIn</title><path d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433c-1.144 0-2.063-.926-2.063-2.065 0-1.138.92-2.063 2.063-2.063 1.14 0 2.064.925 2.064 2.063 0 1.139-.925 2.065-2.064 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z"/></svg>
|
||||
|
Before Width: | Height: | Size: 626 B |
@@ -1 +0,0 @@
|
||||
<svg fill="#000000" role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>X</title><path d="M14.234 10.162 22.977 0h-2.072l-7.591 8.824L7.251 0H.258l9.168 13.343L.258 24H2.33l8.016-9.318L16.749 24h6.993zm-2.837 3.299-.929-1.329L3.076 1.56h3.182l5.965 8.532.929 1.329 7.754 11.09h-3.182z"/></svg>
|
||||
|
Before Width: | Height: | Size: 315 B |
BIN
public/images/backgrounds/liquid-glass-bg.png
Normal file
|
After Width: | Height: | Size: 2.4 MiB |
|
Before Width: | Height: | Size: 129 KiB |
|
Before Width: | Height: | Size: 214 KiB |
|
Before Width: | Height: | Size: 183 KiB |
|
Before Width: | Height: | Size: 138 KiB |
|
Before Width: | Height: | Size: 112 KiB |
|
Before Width: | Height: | Size: 244 KiB |
|
Before Width: | Height: | Size: 146 KiB |
|
Before Width: | Height: | Size: 123 KiB |
|
Before Width: | Height: | Size: 149 KiB |
|
Before Width: | Height: | Size: 131 KiB |
|
Before Width: | Height: | Size: 224 KiB |
|
Before Width: | Height: | Size: 244 KiB |
|
Before Width: | Height: | Size: 274 KiB |
|
Before Width: | Height: | Size: 285 KiB |
|
Before Width: | Height: | Size: 219 KiB |
|
Before Width: | Height: | Size: 396 KiB |
|
Before Width: | Height: | Size: 279 KiB |
|
Before Width: | Height: | Size: 268 KiB |
|
Before Width: | Height: | Size: 279 KiB |
|
Before Width: | Height: | Size: 241 KiB |
|
Before Width: | Height: | Size: 243 KiB |
|
Before Width: | Height: | Size: 270 KiB |
BIN
public/images/logos/logo-long-black.png
Normal file
|
After Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 477 B After Width: | Height: | Size: 477 B |
|
Before Width: | Height: | Size: 406 KiB After Width: | Height: | Size: 406 KiB |
BIN
public/images/portfolio/dealplustech.png
Normal file
|
After Width: | Height: | Size: 768 KiB |
|
Before Width: | Height: | Size: 241 KiB |
|
Before Width: | Height: | Size: 285 KiB |
|
Before Width: | Height: | Size: 285 KiB |
|
Before Width: | Height: | Size: 268 KiB |
|
Before Width: | Height: | Size: 270 KiB |
19
redesign-input/README.md
Normal file
@@ -0,0 +1,19 @@
|
||||
# MoreminiMore Redesign Input
|
||||
|
||||
ชุดนี้คือข้อมูลที่ extract ออกจากเว็บเดิมก่อนรื้อใหม่ ใช้เป็นฐานสำหรับวางแผน redesign รอบถัดไป
|
||||
|
||||
## Files
|
||||
|
||||
- `WEBSITE-CONTENT-EXTRACT.md` - สรุปเนื้อหาเว็บที่ควรพกต่อไป
|
||||
- `assets/logos/` - logo files ที่ใช้ได้ต่อ
|
||||
- `assets/portfolio/` - ภาพผลงาน portfolio
|
||||
- `raw/src-content/` - content collection เดิมแบบ raw
|
||||
- `raw/src-data/` - data files เดิมแบบ raw
|
||||
- `raw/BRAND-VOICE.md` - brand voice เดิม
|
||||
- `raw/moreminimore-content.md` - planning/content draft เดิม
|
||||
|
||||
## Important Note
|
||||
|
||||
โค้ด implementation เก่า, build output, mockup, และไฟล์ทดลอง ถูกย้ายไปไว้ที่:
|
||||
|
||||
`_archive/pre-redesign-2026-06-21/`
|
||||
177
redesign-input/WEBSITE-CONTENT-EXTRACT.md
Normal file
@@ -0,0 +1,177 @@
|
||||
# MoreminiMore Website Content Extract
|
||||
|
||||
Extract date: 2026-06-21
|
||||
|
||||
เอกสารนี้ดึงเฉพาะเนื้อหาและ asset สำคัญจากเว็บเดิม เพื่อใช้วางแผนใหม่ ไม่ถือว่าเป็น design direction ใหม่
|
||||
|
||||
## Brand
|
||||
|
||||
- Brand name: MoreminiMore
|
||||
- Business: ที่ปรึกษาด้านเว็บไซต์ การตลาดออนไลน์ AI และระบบอัตโนมัติสำหรับ SME ไทย
|
||||
- Core promise: เพิ่มยอดขาย ลดต้นทุน ประหยัดเวลา
|
||||
- Positioning: เริ่มจากดูข้อมูลจริงก่อน แล้วค่อยเลือกสิ่งที่ควรทำ
|
||||
- Memorable line from brand voice: เป้าหมายของเราคือการเพิ่มกำไรให้ลูกค้า
|
||||
- Tone: ตรง สุภาพ เน้นข้อมูล ไม่ขายฝัน ไม่ทำให้เทคโนโลยีดูยากเกินจำเป็น
|
||||
- Primary CTA: ปรึกษาฟรี 30 นาที
|
||||
- Secondary CTA: ดูผลงานจริง
|
||||
|
||||
## Contact
|
||||
|
||||
- Email: contact@moreminimore.com
|
||||
- Phone: 080-995-5945
|
||||
- Address: 53 หมู่ 1 ต.บ้านแพ้ว อ.บ้านแพ้ว สมุทรสาคร 74120
|
||||
- Facebook: https://www.facebook.com/moreminimore
|
||||
- LINE: https://line.me/ti/p/~539hdlul
|
||||
- LINE ID: @moreminimore
|
||||
- LinkedIn: https://www.linkedin.com/company/moreminimore
|
||||
|
||||
## Navigation Candidates
|
||||
|
||||
- หน้าแรก
|
||||
- บริการ
|
||||
- ผลงาน
|
||||
- บทความ
|
||||
- FAQ
|
||||
- เกี่ยวกับ
|
||||
- ติดต่อ
|
||||
|
||||
## Homepage Content To Preserve
|
||||
|
||||
### Hero
|
||||
|
||||
- Headline option currently used: เพิ่มยอดขาย ลดต้นทุน ประหยัดเวลา
|
||||
- Supporting copy: ที่ปรึกษาด้านเว็บไซต์ การตลาดออนไลน์ AI และระบบอัตโนมัติสำหรับ SME ไทย เริ่มจากดูข้อมูลจริงก่อน แล้วค่อยเลือกสิ่งที่ควรทำ
|
||||
|
||||
### Data First Section
|
||||
|
||||
- Heading: เราใช้ข้อมูลจริง เพื่อวางแผนให้คุ้มกว่าเดิม
|
||||
- Copy: ก่อนเสนอเว็บไซต์ แคมเปญ หรือระบบอัตโนมัติ เราดูข้อมูลจริงก่อนเสมอ ทั้งเว็บเดิม ช่องทางการตลาด พฤติกรรมลูกค้า ผู้สนใจที่ติดต่อเข้ามา และขั้นตอนทำงานของทีม
|
||||
- Metrics:
|
||||
- +373% impression จากเคส Dataroot
|
||||
- +114.2% click หลังปรับกลุ่มเป้าหมาย
|
||||
- -28.3% ad spend จากข้อมูลที่ยืนยันแล้ว
|
||||
|
||||
### Process
|
||||
|
||||
- ดูข้อมูล: เข้าใจตัวเลข เว็บไซต์ ช่องทางขาย และขั้นตอนทำงานเดิม
|
||||
- เลือกทางที่คุ้ม: เลือกสิ่งที่ควรทำก่อนจากโจทย์จริง
|
||||
- ลงมือทำ: สร้างเว็บ แคมเปญ ระบบอัตโนมัติ หรือวิธีใช้ AI ที่ใช้งานได้จริง
|
||||
- วัดผลและปรับต่อ: ดูผลหลังใช้งาน แล้วปรับให้คุ้มขึ้น
|
||||
|
||||
### Final CTA
|
||||
|
||||
- Heading: ไม่แน่ใจว่าควรเริ่มตรงไหน คุยกับเราก่อน
|
||||
- Copy: เล่าโจทย์ของธุรกิจคุณให้เราฟัง เราจะช่วยดูว่าควรเริ่มจากเว็บไซต์ การตลาด ระบบอัตโนมัติ หรือ AI
|
||||
|
||||
## Services
|
||||
|
||||
### Website Development
|
||||
|
||||
- Short: สร้างเว็บไซต์ที่โหลดไว แก้ไขง่าย วัดผลได้ และเป็นฐานหลักของการขายออนไลน์
|
||||
- Hero title: เว็บไซต์ที่แก้เองได้ โหลดไว และพร้อมวัดผล
|
||||
- Hero subtitle: สร้างเว็บไซต์ธุรกิจที่เป็นฐานหลักของการขายออนไลน์ พร้อม SEO โครงสร้างหน้า และช่องทางรับลูกค้าใหม่
|
||||
- Problems:
|
||||
- เว็บเดิมโหลดช้า
|
||||
- แก้ไขเนื้อหาเองไม่ได้
|
||||
- ไม่มีระบบวัดผล
|
||||
- SEO และโครงสร้างหน้ายังไม่พร้อม
|
||||
- ลูกค้าเข้าเว็บแล้วไม่รู้ว่าต้องทำอะไรต่อ
|
||||
|
||||
### Marketing Consult
|
||||
|
||||
- Short: ดูข้อมูลการตลาดเดิม แล้วปรับกลุ่มเป้าหมาย ช่องทาง และข้อความขายให้ใช้งบคุ้มขึ้น
|
||||
- Hero title: การตลาดที่เริ่มจากข้อมูล ไม่ใช่ความรู้สึก
|
||||
- Hero subtitle: เราช่วยดูข้อมูลการตลาดเดิม วิเคราะห์ช่องทาง กลุ่มเป้าหมาย และข้อความขาย เพื่อเลือกสิ่งที่ควรปรับให้ใช้งบคุ้มขึ้น
|
||||
- Problems:
|
||||
- ยิงแอดแล้วไม่คุ้ม
|
||||
- ยอดขายไม่เพิ่มแม้ใช้งบมากขึ้น
|
||||
- มีคนทักเข้ามา แต่ไม่ใช่ลูกค้าที่มีคุณภาพ
|
||||
- ไม่รู้ว่าควรทำช่องทางไหนต่อ
|
||||
- คอนเทนต์ไม่เชื่อมกับการขาย
|
||||
|
||||
### Automation Workflow
|
||||
|
||||
- Short: วางระบบทำงานอัตโนมัติสำหรับงานที่มีขั้นตอนแน่นอน ช่วยให้ทีมไม่ต้องเสียเวลากับงานซ้ำ
|
||||
- Hero title: ลดงานซ้ำ ด้วยระบบการทำงานอัตโนมัติ
|
||||
- Hero subtitle: เราช่วยวางระบบอัตโนมัติด้วยการเขียนแอปหรือเชื่อมต่อเครื่องมือที่มีอยู่ เพื่อให้งานที่มีขั้นตอนชัดเจนทำงานได้เร็วขึ้น และลดเวลาที่พนักงานต้องทำซ้ำ
|
||||
- Problems:
|
||||
- พนักงานต้อง copy/paste ข้อมูลซ้ำ
|
||||
- งานมีขั้นตอนชัดเจน แต่ยังต้องทำมือ
|
||||
- ข้อมูลกระจายหลายที่
|
||||
- ผู้สนใจหรืองานเอกสารหลุดระหว่างทาง
|
||||
- ผู้จัดการต้องตามงานเดิมซ้ำ ๆ
|
||||
|
||||
### AI Consult
|
||||
|
||||
- Short: ออกแบบวิธีใช้ AI ให้ทำงานร่วมกับพนักงาน และช่วยเก็บความรู้สำคัญไว้ในองค์กร
|
||||
- Hero title: ให้ AI ทำงานร่วมกับพนักงาน และเก็บความรู้ไว้กับองค์กร
|
||||
- Hero subtitle: เราช่วยออกแบบวิธีใช้ AI ให้เข้ากับงานจริงของทีม และค่อย ๆ เก็บความรู้จากพนักงาน เพื่อให้ความรู้สำคัญยังอยู่กับองค์กรแม้มีการเปลี่ยนคน
|
||||
- Problems:
|
||||
- ความรู้สำคัญอยู่กับพนักงานบางคน
|
||||
- พนักงานใหม่ต้องใช้เวลานานในการเรียนรู้งาน
|
||||
- คำถามซ้ำ ๆ ไม่มีแหล่งคำตอบกลาง
|
||||
- เอกสารกระจัดกระจาย
|
||||
- ใช้ AI แบบทดลอง แต่ยังไม่เชื่อมกับงานจริง
|
||||
|
||||
## Portfolio
|
||||
|
||||
| Name | URL | Category | Image |
|
||||
| --- | --- | --- | --- |
|
||||
| Dataroot | https://erp.dataroot.asia | ที่ปรึกษาการตลาด | `assets/portfolio/dataroot.png` |
|
||||
| ทวนทอง 99 | https://tuanthong99.com | อีคอมเมิร์ซ | `assets/portfolio/tuanthong.png` |
|
||||
| Underdog Marketing | https://underdog.run | Website Development | `assets/portfolio/underdog.png` |
|
||||
| เทรนเนอร์ซันนี่ | https://trainersunny.com | Website Development | `assets/portfolio/trainersunny.png` |
|
||||
| Lungfinler | https://lungfinler.com | Website Development | `assets/portfolio/lungfinler.png` |
|
||||
| Jet Industries | https://jetindustries.co.th | Website Development | `assets/portfolio/jetindustries.png` |
|
||||
| สำนักงานกฎหมาย ตถาตา | https://lawyernoom.com | Website Development | `assets/portfolio/lawyernoom.png` |
|
||||
| Baofuling Shop | https://baofulingshop.com | อีคอมเมิร์ซ | `assets/portfolio/baofuling.png` |
|
||||
| เลือดจระเข้วานิไทย | https://เลือดจระเข้วานิไทย.com | อีคอมเมิร์ซ | `assets/portfolio/luadjob.png` |
|
||||
|
||||
## Blog Content
|
||||
|
||||
Raw blog posts are preserved in `raw/src-content/blog/`.
|
||||
|
||||
- 5 วิธีใช้ AI เพิ่มยอดขายให้ธุรกิจของคุณ
|
||||
- วิธีสร้าง Content ด้วย AI ที่ Google รัก
|
||||
- AI สำหรับ SME ไทย: คู่มือฉบับสมบูรณ์
|
||||
- Digital Transformation Guide
|
||||
- Marketing Automation Guide
|
||||
|
||||
## FAQ Content
|
||||
|
||||
Raw FAQ entries are preserved in `raw/src-content/faq/`.
|
||||
|
||||
Categories found:
|
||||
|
||||
- บริการ
|
||||
- ราคา
|
||||
- เวลา
|
||||
- AI
|
||||
- Support
|
||||
|
||||
## Assets
|
||||
|
||||
### Logos
|
||||
|
||||
- `assets/logos/logo-long-black.png`
|
||||
- `assets/logos/logo-long.png`
|
||||
- `assets/logos/logo.svg`
|
||||
|
||||
### Portfolio Images
|
||||
|
||||
- `assets/portfolio/baofuling.png`
|
||||
- `assets/portfolio/dataroot.png`
|
||||
- `assets/portfolio/jetindustries.png`
|
||||
- `assets/portfolio/lawyernoom.png`
|
||||
- `assets/portfolio/luadjob.png`
|
||||
- `assets/portfolio/lungfinler.png`
|
||||
- `assets/portfolio/trainersunny.png`
|
||||
- `assets/portfolio/tuanthong.png`
|
||||
- `assets/portfolio/underdog.png`
|
||||
|
||||
## Raw Sources Preserved
|
||||
|
||||
- `raw/src-content/`
|
||||
- `raw/src-data/`
|
||||
- `raw/BRAND-VOICE.md`
|
||||
- `raw/moreminimore-content.md`
|
||||
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
BIN
redesign-input/assets/logos/logo-long.png
Normal file
|
After Width: | Height: | Size: 28 KiB |
6
redesign-input/assets/logos/logo.svg
Normal file
@@ -0,0 +1,6 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 40" fill="none">
|
||||
<rect width="40" height="40" rx="8" fill="#fed400"/>
|
||||
<text x="8" y="28" font-family="Kanit, sans-serif" font-weight="800" font-size="20" fill="#000">M</text>
|
||||
<text x="52" y="26" font-family="Kanit, sans-serif" font-weight="600" font-size="18" fill="#000">M</text>
|
||||
<text x="72" y="26" font-family="Noto Sans Thai, sans-serif" font-weight="500" font-size="14" fill="#000">oreMiniMore</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 477 B |
15
redesign-input/assets/portfolio/DEALPLUSTECH.md
Normal file
@@ -0,0 +1,15 @@
|
||||
# Dealplustech Portfolio Asset
|
||||
|
||||
Dealplustech is included in the rebuilt website portfolio.
|
||||
|
||||
- URL: https://www.dealplustech.co.th
|
||||
- Homepage screenshot captured: `dealplustech.png`
|
||||
- Screenshot status: clean homepage capture with header/menu visible and cookie banner removed.
|
||||
- Target style: same portfolio-image treatment as existing clients
|
||||
- Output filename: `dealplustech.png`
|
||||
|
||||
Notes:
|
||||
|
||||
- Dealplustech is a new client.
|
||||
- It should appear as website portfolio work.
|
||||
- It can also support consulting-adjacent credibility, but should not replace Dataroot main diagnosis story.
|
||||
BIN
redesign-input/assets/portfolio/baofuling.png
Normal file
|
After Width: | Height: | Size: 706 KiB |
BIN
redesign-input/assets/portfolio/dataroot.png
Normal file
|
After Width: | Height: | Size: 406 KiB |
BIN
redesign-input/assets/portfolio/dealplustech.png
Normal file
|
After Width: | Height: | Size: 768 KiB |
BIN
redesign-input/assets/portfolio/jetindustries.png
Normal file
|
After Width: | Height: | Size: 911 KiB |
BIN
redesign-input/assets/portfolio/lawyernoom.png
Normal file
|
After Width: | Height: | Size: 475 KiB |
BIN
redesign-input/assets/portfolio/luadjob.png
Normal file
|
After Width: | Height: | Size: 496 KiB |
BIN
redesign-input/assets/portfolio/lungfinler.png
Normal file
|
After Width: | Height: | Size: 337 KiB |
BIN
redesign-input/assets/portfolio/trainersunny.png
Normal file
|
After Width: | Height: | Size: 849 KiB |
BIN
redesign-input/assets/portfolio/tuanthong.png
Normal file
|
After Width: | Height: | Size: 897 KiB |
BIN
redesign-input/assets/portfolio/underdog.png
Normal file
|
After Width: | Height: | Size: 724 KiB |
80
redesign-input/raw/BRAND-VOICE.md
Normal file
@@ -0,0 +1,80 @@
|
||||
# Brand Voice — MoreminiMore
|
||||
|
||||
> ใช้เป็นกระดาษทดเวลาเขียน content ทุกชิ้น ถ้าเขียนแล้วผิด vibe ให้กลับมาเช็คที่นี่
|
||||
|
||||
---
|
||||
|
||||
## หนึ่งประโยคที่คนต้องจำ
|
||||
|
||||
> **เป้าหมายของเราคือการเพิ่มกำไรให้ลูกค้า** เพราะถ้าลูกค้ามีกำไรมากขึ้น ลูกค้าก็จะสามารถใช้บริการเราต่อไปได้
|
||||
|
||||
---
|
||||
|
||||
## เราเป็นใครใน 1 บรรทัด
|
||||
|
||||
ที่ปรึกษาที่ทำเว็บ + ทำการตลาด + ทำ AI ในองค์กร **โดยใช้ข้อมูลจริงเป็นตัวตั้ง** ไม่ใช่ประสบการณ์ล้วน ๆ
|
||||
|
||||
---
|
||||
|
||||
## เสียงของเรา (10 ข้อ)
|
||||
|
||||
1. **ตรง แต่สุภาพ** — พูดตรง ๆ ว่าทำได้หรือทำไม่ได้ แต่ไม่ดุ ไม่หยาบ
|
||||
2. **เน้นข้อมูล** — เวลาพูดถึงผลงาน บอกตัวเลข ไม่ใช่ "ดีขึ้นมาก" แบบกำกวม
|
||||
3. **เล่าจากประสบการณ์จริง** — มีเคสพัง มีเคสสำเร็จ ไม่อวดว่าทำได้หมดทุกอย่าง
|
||||
4. **ห้ามใช้คำว่า "ครบวงจร" "ทันสมัย" "รวดเร็ว" "ไร้รอยต่อ" "เพิ่มประสิทธิภาพ"** — คำพวกนี้ทุก agency ใช้ ไม่ได้ทำให้เราต่าง
|
||||
5. **พูดถึงเรื่องที่เราไม่เชื่อด้วย** — เว็บสวยไม่ได้แปลว่าขายได้ / AI ไม่ได้แทนทุกอย่าง / จ่ายแพงไม่ได้แปลว่าดี
|
||||
6. **ยอมรับว่าเราเป็น soloprenuer** — แต่ห้ามขอโทษ ห้ามทำเป็นข้ออ่อน ให้ทำเป็นข้อได้เปรียบ: คุณคุยกับคนที่จะทำงานจริง ไม่ใช่ทีมขาย
|
||||
7. **ช่วงราคา** — ไม่ลงเว็บ แต่พร้อมบอกเมื่อถาม ถ้าลูกค้าถามแล้วเราไม่ตอบ = ลูกค้าหาย
|
||||
8. **Quote ลูกค้าใช้ของจริง** — เอาคำที่ลูกค้าพูดจริง ๆ มาวาง ไม่ใช่แต่งให้สวย
|
||||
9. **เน้นว่าเราเลือกช่องทางให้เหมาะกับสินค้า + กลุ่มเป้าหมาย** — ไม่ยิงทุกที่ ไม่ใช้ AI ระดับ Frontier กับทุกงาน
|
||||
10. **พูดถึง "เราเขียนโค้ดเอง" และ "เราตอบแชตเอง" โดยไม่ต้องโอ้อวด** — แค่บอกตรง ๆ ว่าเราไม่ outsource
|
||||
|
||||
---
|
||||
|
||||
## คำที่ห้ามใช้ (Banned Words)
|
||||
|
||||
| ❌ ห้าม | ✅ ใช้แทน |
|
||||
|---|---|
|
||||
| ครบวงจร | บอกชัดว่าทำอะไรบ้าง |
|
||||
| ทันสมัย | บอกว่าใช้เทคโนโลยีอะไร เช่น Astro / n8n / local LLM |
|
||||
| รวดเร็ว | บอกตัวเลข เช่น "ส่งมอบภายใน 14 วัน" |
|
||||
| ไร้รอยต่อ | อธิบายว่าเชื่อมต่อระบบอะไรยังไง |
|
||||
| เพิ่มประสิทธิภาพ | บอกตัวเลข เช่น "ลดเวลา 4 ชม./สัปดาห์" |
|
||||
| หลากหลาย | บอกว่ามีอะไรบ้าง |
|
||||
| มีคุณภาพ | บอกเกณฑ์วัด |
|
||||
|
||||
---
|
||||
|
||||
## คำที่ใช้บ่อย (ใช้ได้)
|
||||
|
||||
- "วางแผนจากข้อมูล" / "ใช้สถิติจริง"
|
||||
- "เราเขียนเอง / ทำเอง" / "ไม่ outsource"
|
||||
- "จ่ายเมื่อใช้ / เริ่มต้นที่..."
|
||||
- "ถ้าทำไม่ได้ จะบอกตรง ๆ"
|
||||
- "เคสเราเคยพังแบบนี้" (เล่าเคสจริง)
|
||||
|
||||
---
|
||||
|
||||
## Tone Examples
|
||||
|
||||
### ❌ ก่อนแก้ (AI-isms + ทั่วไปเกินไป)
|
||||
> เรามีบริการครบวงจร ทั้งเว็บไซต์ การตลาด และ AI เพื่อเพิ่มประสิทธิภาพให้ธุรกิจของคุณอย่างทันสมัยและรวดเร็ว
|
||||
|
||||
### ✅ หลังแก้ (เสียงของมอร์มินิมอร์)
|
||||
> เราทำเว็บ ทำการตลาด และวางระบบ AI ให้องค์กร — ทั้งหมดเริ่มจากดูข้อมูลของลูกค้าก่อน ไม่ใช่เดาจากประสบการณ์
|
||||
|
||||
---
|
||||
|
||||
### ❌ ก่อนแก้
|
||||
> เว็บไซต์ของเราสวยงาม ทันสมัย รองรับทุกอุปกรณ์
|
||||
|
||||
### ✅ หลังแก้
|
||||
> เว็บที่เราทำเน้นให้ขายได้ ไม่ใช่เน้นให้สวย — เพราะเว็บหลายเว็บที่ดูดีที่สุด ขายแย่ที่สุดก็มี
|
||||
|
||||
---
|
||||
|
||||
### ❌ ก่อนแก้
|
||||
> เราใช้ AI เพื่อเพิ่มประสิทธิภาพ
|
||||
|
||||
### ✅ หลังแก้
|
||||
> เราเลือกใช้ AI ตามงาน — งาน 80% ใช้ Model ราคาถูกก็พอ จะได้ไม่เปลืองเงินลูกค้า
|
||||
103
redesign-input/raw/moreminimore-content.md
Normal file
@@ -0,0 +1,103 @@
|
||||
# MoreminiMore — เนื้อหาเว็บไซต์
|
||||
|
||||
## ข้อมูลบริษัท
|
||||
- **ชื่อ**: MoreminiMore
|
||||
- **ประเภทธุรกิจ**: ที่ปรึกษา AI + การตลาดออนไลน์ สำหรับ SME ไทย
|
||||
- **จุดเด่น**: เริ่มจากดูสถิติจริง ไม่ใช่เดาว่าควรทำอะไร
|
||||
- **สัญลักษณ์**: more**mini**more (mini = สีแดง #d4553a)
|
||||
|
||||
---
|
||||
|
||||
## Hero Section
|
||||
- **Headline**: พาธุรกิจคุณ **บินสูง** ด้วยข้อมูล
|
||||
- **Subheadline**: ที่ปรึกษา AI + การตลาดออนไลน์ สำหรับ SME ไทย — เริ่มจากดูสถิติของคุณก่อน
|
||||
- **CTA 1**: ปรึกษาฟรี 30 นาที →
|
||||
- **CTA 2**: ดูผลงานจริง
|
||||
- **Trust badges**: ✓ ปรึกษาฟรี 30 นาที · ✓ ไม่มีผูกมัด · ✓ เห็นผลภายใน 30 วัน
|
||||
|
||||
---
|
||||
|
||||
## Section 1: ผลลัพธ์จริง
|
||||
**หัวข้อ**: เราช่วย SME ไทย บินสูงขึ้น
|
||||
**คำอธิบาย**: ไม่ใช่แค่ทำเว็บ — แต่ช่วยให้ธุรกิจเติบโตจริง ด้วยข้อมูลจริง
|
||||
|
||||
| ตัวเลข | หัวข้อ | รายละเอียด |
|
||||
|--------|--------|-----------|
|
||||
| +373% | เพิ่มยอดขาย | Dataroot +373% impression ใน 1 เดือน |
|
||||
| −28% | ลดต้นทุน | ลดงบโฆษณา 28% โดยยอดขายไม่ลด |
|
||||
| 5 ชม. | ประหยัดเวลา | AI + Automation ทำงานแทน 5 ชม./วัน |
|
||||
|
||||
---
|
||||
|
||||
## Section 2: Case Study / Dataroot
|
||||
**หัวข้อ**: จากยิงโฆษณาแบบกว้าง สู่ผลลัพธ์ที่แม่นยำ
|
||||
**Quote**: "เราไม่ได้ยิงโฆษณาเก่ง เราแค่ดูสถิติ"
|
||||
|
||||
### ขั้นตอน:
|
||||
1. **วิเคราะห์ข้อมูล 3 เดือนย้อนหลัง** — ดูสถิติจริง ไม่ใช่เดา
|
||||
2. **แยกกลุ่มเป้าหมาย: 4 segments** — ยิงให้แม่น ไม่ใช่ยิงให้กว้าง
|
||||
3. **ได้ผลลัพธ์ +373% impression** — วัดผลได้จริง
|
||||
|
||||
### ตัวเลข:
|
||||
- +373% IMPRESSION
|
||||
- +114% CLICK
|
||||
- −28% AD_SPEND
|
||||
|
||||
**CTA**: อ่านเคสเต็ม →
|
||||
|
||||
---
|
||||
|
||||
## Section 3: บริการ
|
||||
**หัวข้อ**: เราทำอะไรได้บ้าง
|
||||
|
||||
| ไอคอน | บริการ | คำอธิบาย |
|
||||
|--------|--------|----------|
|
||||
| 🌐 | รับทำเว็บไซต์ | เว็บที่ Google รัก + โหลดเร็ว ไม่ใช่แค่สวย |
|
||||
| 🤖 | ที่ปรึกษา AI | AI ที่ใช้ได้จริงกับธุรกิจ ไม่ใช่แค่ buzzword |
|
||||
| 📈 | การตลาดออนไลน์ | SEO + Ads + Content ที่วัดผลได้ |
|
||||
| ⚡ | Automation | ทำงานแทน 5 ชม./วัน ด้วย AI |
|
||||
|
||||
---
|
||||
|
||||
## Section 4: ขั้นตอนทำงาน
|
||||
**หัวข้อ**: เราทำงานยังไง
|
||||
|
||||
| ขั้น | หัวข้อ | รายละเอียด |
|
||||
|------|--------|-----------|
|
||||
| 01 | ดูสถิติ | วิเคราะห์ข้อมูลปัจจุบัน — ไม่ใช่เดา |
|
||||
| 02 | วางแผน | กลยุทธ์ที่เหมาะกับธุรกิจคุณ |
|
||||
| 03 | ลงมือทำ | ทีมเราทำงานเอง — ไม่ outsource |
|
||||
| 04 | วัดผล | รายงานผลลัพธ์จริง — ไม่ใช่ vanity metrics |
|
||||
|
||||
---
|
||||
|
||||
## Section 5: บล็อก
|
||||
**หัวข้อ**: บทความล่าสุด
|
||||
|
||||
| ไอคอน | หัวข้อ | คำอธิบาย |
|
||||
|--------|--------|----------|
|
||||
| 📊 | 5 วิธีใช้ AI เพิ่มยอดขาย | เริ่มได้เลยวันนี้ |
|
||||
| 🎯 | Content แบบไหน Google รัก | อัปเดต SEO 2026 |
|
||||
| 🔧 | Automation 101 | เริ่มยังไงให้ได้ผล |
|
||||
|
||||
---
|
||||
|
||||
## Section 6: Contact
|
||||
**หัวข้อ**: พร้อมที่จะบินสูงขึ้นหรือยัง?
|
||||
**คำอธิบาย**: ปรึกษาฟรี 30 นาที — ไม่มีผูกมัด
|
||||
**CTA 1**: ปรึกษาฟรี →
|
||||
**CTA 2**: ดูผลงานจริง
|
||||
|
||||
---
|
||||
|
||||
## Navigation
|
||||
- เกี่ยวกับ
|
||||
- บริการ
|
||||
- ผลงาน
|
||||
- ปรึกษาฟรี → (CTA button)
|
||||
|
||||
---
|
||||
|
||||
## ภาษา
|
||||
- **ภาษาไทย** ทั้งหมด
|
||||
- **Font**: Kanit (หัวข้อ), Itim (เนื้อหา), JetBrains Mono (labels/eyebrow)
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
category: "บริการ"
|
||||
category_icon: "💼"
|
||||
question: "มอร์มินิมอร์ทำอะไรบ้าง?"
|
||||
answer: "4 บริการหลัก — (1) รับทำเว็บไซต์ (Astro / WordPress) (2) ที่ปรึกษาการตลาดออนไลน์ (3) Automation / เชื่อมต่อระบบ (4) AI Consult ในองค์กร ทั้งหมดเริ่มจากดูข้อมูลของลูกค้าก่อน ไม่ใช่เดาว่าควรทำอะไร"
|
||||
---
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
category: "บริการ"
|
||||
category_icon: "💼"
|
||||
question: "ถ้ามีงบน้อย ควรเริ่มจากอะไร?"
|
||||
answer: "ถ้ายังไม่มีเว็บและไม่มีกิจกรรมออนไลน์เลย → เริ่มจากเว็บไซต์ก่อน เพราะเป็นบริการที่ถูกที่สุด ถ้ามีเว็บแล้วและมีกิจกรรมออนไลน์ → Marketing Consult จะคุ้มกว่า ถ้ารู้สึกยุ่งมากมีแต่ความผิดพลาด → Automation จะตอบโจทย์สุด ถ้ามีระบบพร้อมแล้วอยากรีดยอดขายหรือป้องกันปัญหาพนักงานลาออก → AI Consult"
|
||||
---
|
||||
6
redesign-input/raw/src-content/faq/003-services-fit.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
category: "บริการ"
|
||||
category_icon: "💼"
|
||||
question: "เหมาะกับธุรกิจแบบไหน?"
|
||||
answer: "SME ที่ต้องการคนช่วยดูเรื่อง Online Marketing และระบบ IT ลูกค้าที่ไม่มีความรู้ IT มาก แต่จำเป็นต้องใช้ระบบ IT ในการทำงาน ไม่เหมาะกับ: องค์กรขนาดใหญ่ที่มีการเมืองเยอะ คนที่อยากได้ของฟรีหรือจ่ายน้อยแต่คาดหวังงานระดับแสน และกลุ่ม IT ทั่วไป (ยกเว้นขาย Software เฉพาะทาง เช่น ERP)"
|
||||
---
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
category: "บริการ"
|
||||
category_icon: "💼"
|
||||
question: "รับงานอุตสาหกรรมเฉพาะไหม?"
|
||||
answer: "รับหลากหลาย แต่ไม่รับทุกอย่าง — เราเน้นงานที่วัดผลได้ ไม่ว่าจะเป็น E-commerce, บริการ, B2B, คลินิก, ร้านอาหาร, ผู้ผลิต, สถานศึกษา, ที่ปรึกษา ดูตัวอย่างงานได้ที่หน้า Portfolio ถ้าไม่แน่ใจว่าอุตสาหกรรมของคุณเหมาะ นัดคุย 30 นาทีฟรีได้เลย"
|
||||
---
|
||||
6
redesign-input/raw/src-content/faq/005-price-start.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
category: "ราคา"
|
||||
category_icon: "💰"
|
||||
question: "ราคาเริ่มต้นเท่าไหร่?"
|
||||
answer: "เว็บไซต์: Astro เริ่ม 5,000 บาท / WordPress เริ่ม 30,000 บาท (ขึ้นอยู่กับความซับซ้อน) · ที่ปรึกษา Marketing และ Automation: เริ่ม 10,000 บาท/เดือน · ที่ปรึกษา AI: เริ่ม 20,000 บาท/เดือน · Host: เริ่ม 5,000 บาท/ปี ราคาจะขึ้นอยู่กับ Requirement จริง บอกได้เมื่อคุยกัน"
|
||||
---
|
||||
6
redesign-input/raw/src-content/faq/006-price-packages.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
category: "ราคา"
|
||||
category_icon: "💰"
|
||||
question: "มีแพ็คเกจไหม?"
|
||||
answer: "ไม่มีแพ็คเกจตายตัว เพราะงานแต่ละชิ้นต่างกัน บางเว็บใช้เวลา 1 สัปดาห์ บางเว็บใช้ 3 เดือน เราจะส่ง Proposal เป็น PDF พร้อมรายละเอียดงาน ราคา ระยะเวลา ให้คุณอ่านก่อนเซ็น แก้ไข scope ได้"
|
||||
---
|
||||
6
redesign-input/raw/src-content/faq/007-price-payment.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
category: "ราคา"
|
||||
category_icon: "💰"
|
||||
question: "จ่ายยังไง?"
|
||||
answer: "เว็บไซต์: มัดจำ 50% ตอนเซ็น ที่เหลือจ่ายตอนส่งมอบ · ที่ปรึกษารายเดือน: จ่ายต้นเดือนของทุกเดือน เริ่มจ่ายเดือนแรกตอนเซ็นสัญญา ออกใบกำกับภาษีได้"
|
||||
---
|
||||
6
redesign-input/raw/src-content/faq/008-price-hidden.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
category: "ราคา"
|
||||
category_icon: "💰"
|
||||
question: "มีค่าใช้จ่ายแอบแฝงไหม?"
|
||||
answer: "ไม่มี — เราจะบอกทุกค่าใช้จ่ายใน Proposal ตั้งแต่ต้น ไม่มี \"อันนี้เพิ่มเงินนะ\" ตอนใกล้ส่งมอบ ถ้ามีงานเพิ่มจริง ๆ จะคุยและตกลงราคาก่อนทำ"
|
||||
---
|
||||
6
redesign-input/raw/src-content/faq/009-time-website.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
category: "ระยะเวลา"
|
||||
category_icon: "⏱️"
|
||||
question: "ทำเว็บเสร็จในกี่วัน?"
|
||||
answer: "Astro: 14-30 วัน · WordPress: 2-4 เดือน · ถ้าจะติด เราจะบอกก่อน 7 วัน ไม่ใช่บอกตอนส่งงาน — เคสไหนที่เคยส่งช้า เราคืนเงิน Pro-rata"
|
||||
---
|
||||
6
redesign-input/raw/src-content/faq/010-time-seo.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
category: "ระยะเวลา"
|
||||
category_icon: "⏱️"
|
||||
question: "SEO ใช้เวลาเห็นผลกี่เดือน?"
|
||||
answer: "SEO ปกติใช้เวลา 3-6 เดือนถึงจะเห็นผลชัด ขึ้นอยู่กับคีย์เวิร์ดและคู่แข่ง เราเคยมีเคสติดหน้า 1 Google ใน 4 เดือน แต่ก็มีเคสที่ใช้เวลานานกว่านั้น จะบอกคุณตรง ๆ ตั้งแต่แรกว่าคาดว่าเห็นผลเมื่อไหร่"
|
||||
---
|
||||
6
redesign-input/raw/src-content/faq/011-time-rush.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
category: "ระยะเวลา"
|
||||
category_icon: "⏱️"
|
||||
question: "งานด่วน ทำได้ไหม?"
|
||||
answer: "ทำได้ แต่จะคิดราคาเร่งด่วนเพิ่ม เพราะกระทบกับงานอื่นที่มีอยู่ เราจะบอกชัดว่าค่าเร่งเท่าไหร่ก่อนรับงาน"
|
||||
---
|
||||
6
redesign-input/raw/src-content/faq/012-time-overrun.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
category: "ระยะเวลา"
|
||||
category_icon: "⏱️"
|
||||
question: "ถ้างานล่าช้า คืนเงินไหม?"
|
||||
answer: "ถ้าเราส่งงานล่าช้าโดยไม่ได้แจ้งล่วงหน้า 7 วัน จะคืนเงิน Pro-rata ตามจริง เคสนี้เคยเกิดขึ้น 1-2 ครั้งในรอบหลายปี และคืนเงินไปแล้ว"
|
||||
---
|
||||
6
redesign-input/raw/src-content/faq/013-ai-quality.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
category: "AI & เทคนิค"
|
||||
category_icon: "🤖"
|
||||
question: "AI ใช้ของแพงหรือของถูก?"
|
||||
answer: "เราเลือกตามงาน ไม่ใช่เลือกของแพงสุดเสมอ งาน 80% ใช้ Model ราคาถูก (เช่น GPT-4o-mini, Haiku, Local LLM) ก็ได้ผล ส่วนงานที่ซับซ้อนมาก ๆ ค่อยใช้ของแพง วิธีนี้ช่วยลูกค้าประหยัดค่าใช้จ่ายได้มากกว่าครึ่ง"
|
||||
---
|
||||
6
redesign-input/raw/src-content/faq/014-ai-technical.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
category: "AI & เทคนิค"
|
||||
category_icon: "🤖"
|
||||
question: "ต้องมีความรู้เทคนิคไหม?"
|
||||
answer: "ไม่ต้อง เราดูแลตั้งแต่ต้นจนจบ ตั้งแต่วิเคราะห์ ออกแบบ พัฒนา ไปจนถึง Deploy และดูแลหลังขาย จะสอนการใช้งานจนทีมคุณใช้เป็น"
|
||||
---
|
||||
6
redesign-input/raw/src-content/faq/015-ai-pdpa.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
category: "AI & เทคนิค"
|
||||
category_icon: "🤖"
|
||||
question: "ข้อมูลปลอดภัยไหม (PDPA)?"
|
||||
answer: "ปลอดภัย สำหรับงานที่ต้องการความลับ เราใช้ Local LLM ที่รันในเครื่องของลูกค้า ข้อมูลไม่ออกไปไหน ส่วนงานทั่วไปใช้ API ของผู้ให้บริการที่เชื่อถือได้ พร้อมทำ NDA ได้"
|
||||
---
|
||||
6
redesign-input/raw/src-content/faq/016-ai-which.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
category: "AI & เทคนิค"
|
||||
category_icon: "🤖"
|
||||
question: "ควรใช้ AI ตัวไหน?"
|
||||
answer: "ขึ้นอยู่กับงาน ถ้าเป็นแชทบอททั่วไป ใช้ GPT-4o-mini หรือ Claude Haiku ก็พอ ถ้าเป็นงานวิเคราะห์ข้อมูล ใช้ GPT-4o หรือ Claude Sonnet ถ้าเป็นงานที่ต้องการความลับ ใช้ Local LLM (Llama, Qwen) เรามี AI Audit ฟรี ช่วยวิเคราะห์ว่าธุรกิจคุณควรใช้ AI ตัวไหน"
|
||||
---
|
||||