feat: liquid glass UI, blob background, redesign home/portfolio/about pages
- Liquid glass effect on navbar/cards with backdrop-filter invert - Animated blob gradient background (SVG-based) - Portfolio section: scene-dark invert, show 5 items on home - How Work section: step flow with numbers + connecting lines - Hero: Decision snapshot replacing problem selector - About page: inverted background with contrast fixes - Fix parallax JS bundling via Astro - Fix navbar fixed positioning after liquid glass CSS - Submenu hover fix - Clean up removed legacy files/assets
3
.gitignore
vendored
@@ -23,3 +23,6 @@ pnpm-debug.log*
|
|||||||
# jetbrains setting folder
|
# jetbrains setting folder
|
||||||
.idea/
|
.idea/
|
||||||
.hermes/
|
.hermes/
|
||||||
|
|
||||||
|
# archive (large local files)
|
||||||
|
_archive/
|
||||||
|
|||||||
111
BLOG-TOPICS.md
@@ -1,111 +0,0 @@
|
|||||||
# Blog Topics — 5 เรื่องที่ควรเขียน
|
|
||||||
|
|
||||||
> เรียงตามลำดับที่ควรเขียน เริ่มจากเรื่องที่ "อยู่ในใจลูกค้ามากที่สุด" ก่อน
|
|
||||||
> แต่ละเรื่องมี: ที่มา (จากคำตอบข้อไหน) + โครงสร้าง outline + เหตุผลที่ควรเขียน
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 1. "SME ไทยเสียเงินหลายแสนกับโฆษณาที่ไม่มีใครซื้อ — เรื่องจริงจากคนทำ"
|
|
||||||
|
|
||||||
**ที่มา:** A6 (SME ไทยทำพลาดเรื่องเดิมซ้ำ ๆ) + เคส Dataroot + เคสเกือบพังเรื่องกลุ่มเป้าหมาย
|
|
||||||
|
|
||||||
**ทำไมต้องเขียน:** คือเคส flagship ของเรา เขียนครั้งเดียวใช้ได้หลายที่ — เว็บ, LinkedIn, ใบเสนอราคา
|
|
||||||
|
|
||||||
**Outline:**
|
|
||||||
- เริ่มจากเคส Dataroot: คลิกเยอะ ยอดไม่ขยับ งบหลายแสน/เดือน
|
|
||||||
- ดูสถิติย้อนหลัง → เจอว่าคลิกมาจากกลุ่มที่ไม่ซื้อ
|
|
||||||
- ปรับ 3 อย่าง: ตัดกลุ่ม, ปรับ Creative, ขยายช่องทาง
|
|
||||||
- ผลลัพธ์ (Impression ↑373%, Click ↑114%, Ad spend ↓28%)
|
|
||||||
- เคสเกือบพัง: ยิงไปกลุ่ม "คนสนใจเรื่องเงิน" → มีแต่คนมาขอกู้
|
|
||||||
- บทเรียน: ดู "คนที่จะซื้อ" ไม่ใช่ "คนที่คลิกง่าย"
|
|
||||||
|
|
||||||
**Length:** 1,500-2,000 คำ
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 2. "AI ไม่ได้แพงเสมอไป — งาน 80% ใช้ Model ถูกก็พอ ประหยัดได้ครึ่ง"
|
|
||||||
|
|
||||||
**ที่มา:** D15 (เรื่องที่ไม่เห็นด้วย) + A6 (SME ใช้ AI ผิดแบบ) + คำตอบ B7 (AI Consult)
|
|
||||||
|
|
||||||
**ทำไมต้องเขียน:** ลูกค้า SME ส่วนใหญ่กลัว "AI แพง" — ถ้าเขียนเรื่องนี้ได้ดี คือ lead magnet เลย
|
|
||||||
|
|
||||||
**Outline:**
|
|
||||||
- เปิดด้วย: "ถ้าคุณจ่าย GPT-4 ทุกครั้ง คุณกำลังเปลืองเงินเปล่า ๆ"
|
|
||||||
- งานแบ่งเป็น 3 ระดับ: งานทั่วไป, งานวิเคราะห์, งานเฉพาะทาง
|
|
||||||
- ตารางเปรียบเทียบ: งาน X ใช้ Model Y คุณภาพ Z ราคาเท่าไหร่
|
|
||||||
- ตัวอย่างจริง: ลูกค้าเคยใช้ GPT-4 ทุกงาน → ลดเหลือ GPT-4o-mini + Sonnet + Local LLM → ประหยัด 60%
|
|
||||||
- Local LLM คืออะไร + เหมาะกับงานแบบไหน (PDPA, ความลับ)
|
|
||||||
- วิธีเลือก Model: ถ้างานเป็น "ตอบคำถาม" → ใช้ของถูก / ถ้าเป็น "วิเคราะห์ข้อมูล" → ใช้ของกลาง
|
|
||||||
|
|
||||||
**Length:** 1,500-2,000 คำ
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 3. "เว็บสวย vs เว็บขายได้ — ทำไมหลายเว็บที่ดูรก ๆ ถึงขายดีกว่า"
|
|
||||||
|
|
||||||
**ที่มา:** D15 (เว็บสวยไม่ได้แปลว่าขายได้)
|
|
||||||
|
|
||||||
**ทำไมต้องเขียน:** ลูกค้า SME ส่วนใหญ่ตัดสิน agency ด้วย "ผลงานสวยไหม" — ถ้าเขียนเรื่องนี้ได้ ลูกค้าจะเริ่มคิดใหม่
|
|
||||||
|
|
||||||
**Outline:**
|
|
||||||
- ตัวอย่าง: เว็บ A ดูหรูหรา แต่ Conversion 0.5% / เว็บ B ดูเก่า แต่ Conversion 3.2%
|
|
||||||
- ทำไม: เว็บสวยเน้น "ภาพลักษณ์" / เว็บขายได้เน้น "ลูกค้าทำอะไรได้"
|
|
||||||
- หลักการเว็บที่ขายได้: Clear CTA, Trust signals, Friction ต่ำ, Mobile-first
|
|
||||||
- เคสของเรา: เว็บที่ดูไม่หรูแต่ขายได้ (Baofuling, Tuanthong, Jet Industries)
|
|
||||||
- "เว็บสวย vs เว็บขายได้ ไม่ได้แยกกันเสมอ — แต่ถ้าต้องเลือก เราเลือกขายได้"
|
|
||||||
|
|
||||||
**Length:** 1,200-1,500 คำ
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 4. "5 ค่าใช้จ่ายแฝงที่ทำให้ร้านออนไลน์ขาดทุน — แม้ยอดขายจะเติบโต"
|
|
||||||
|
|
||||||
**ที่มา:** เคสเกือบพังเรื่อง Platform fees + A6 (SME ทดลองตลาดใหม่โดยไม่คำนวณค่าใช้จ่ายแฝง)
|
|
||||||
|
|
||||||
**ทำไมต้องเขียน:** ลูกค้า E-commerce เจอปัญหานี้เยอะมาก แต่ไม่ค่อยมีใครเขียนเรื่องนี้
|
|
||||||
|
|
||||||
**Outline:**
|
|
||||||
- ค่าใช้จ่ายแฝง 5 อย่าง: ค่าธรรมเนียม Platform / ค่าจัดส่งที่แท้จริง / ค่าคืนสินค้า / ส่วนลดที่ไม่ได้คิด / ค่าโฆษณาต่อ Lead
|
|
||||||
- เคสจริง: ร้านค้าออนไลน์ขายดี ยอดเดือนละ 500,000 แต่เหลือกำไร 15,000
|
|
||||||
- วิธีคำนวณ: ทำ Spreadsheet ต้นทุนแท้จริง (เอา Template ไปด้วย)
|
|
||||||
- วิธีแก้: ปรับราคา + เพิ่มช่องทางขายตรง
|
|
||||||
- ผลลัพธ์: ลูกค้าเราเพิ่มกำไรต่อชิ้น 35% ใน 2 เดือน
|
|
||||||
|
|
||||||
**Length:** 1,500 คำ
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 5. "GEO คืออะไร และทำไม SEO แบบเดิมอาจไม่พอในยุค ChatGPT"
|
|
||||||
|
|
||||||
**ที่มา:** A6 (รูปแบบการตลาดใหม่ ๆ ที่จะเปลี่ยนไปในยุค AI) + C13 (กำลังเรียนรู้ SEO กับ GEO)
|
|
||||||
|
|
||||||
**ทำไมต้องเขียน:** ยังเป็นเรื่องใหม่สำหรับ SME ส่วนใหญ่ ถ้าเขียนก่อน คุณจะเป็น authority ในเรื่องนี้
|
|
||||||
|
|
||||||
**Outline:**
|
|
||||||
- เปิดด้วย: "ปี 2024 คนเริ่มถาม ChatGPT แทน Google — เว็บคุณอยู่ในคำตอบไหม?"
|
|
||||||
- SEO vs GEO: ต่างกันยังไง
|
|
||||||
- ตัวอย่าง: ถาม ChatGPT "ที่ปรึกษา AI ในไทย" — ได้คำตอบแบบไหน เว็บไหนถูกอ้างอิง
|
|
||||||
- 3 สิ่งที่ต้องทำเพื่อให้ AI อ้างอิงเว็บคุณ: โครงสร้างข้อมูล, Authority, Mention ในแหล่งอื่น
|
|
||||||
- เคสของเรา: ทำให้ลูกค้าโผล่ใน ChatGPT/Perplexity
|
|
||||||
- 2026 คือปีที่ GEO สำคัญกว่า SEO — เตรียมตัวยังไง
|
|
||||||
|
|
||||||
**Length:** 1,500-2,000 คำ
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## เขียนยังไงให้ได้ผล
|
|
||||||
|
|
||||||
**Tone:** ตรง ๆ มีตัวเลข เล่าเคสจริง ไม่ขายของ — เหมือนคุยกับเพื่อนที่เป็น SME
|
|
||||||
|
|
||||||
**โครงสร้าง:** ปัญหา → ตัวอย่างจริง → วิธีแก้ → ผลลัพธ์ (ถ้ามี) → บทเรียน/ข้อคิด
|
|
||||||
|
|
||||||
**สิ่งที่ไม่ควรทำ:**
|
|
||||||
- ไม่ขายบริการตรง ๆ ใน blog — ให้คนอ่านแล้วเกิดความเชื่อถือ แล้วเขาจะกลับมาเอง
|
|
||||||
- ไม่ใช้ "ครบวงจร ทันสมัย" — ใช้ตัวเลขแทน
|
|
||||||
- ไม่อ้างอิง source ที่ไม่มีจริง
|
|
||||||
|
|
||||||
**SEO:** แต่ละ blog ควรมี:
|
|
||||||
- Title ที่มีคีย์เวิร์ด (เช่น "AI ไม่ได้แพงเสมอไป")
|
|
||||||
- Meta description ที่ดึงดูด
|
|
||||||
- Internal link ไปหน้า services/portfolio
|
|
||||||
- CTA ท้ายบทความ: "อยากให้ช่วยดูเคสของคุณ? นัดคุย 30 นาทีฟรี"
|
|
||||||
21
PLAN-REVIEW-LOG.md
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
# Plan Review Log: MoreminiMore Homepage Rebuild
|
||||||
|
|
||||||
|
Act 1 grill complete — plan locked with user.
|
||||||
|
|
||||||
|
MAX_ROUNDS=5
|
||||||
|
|
||||||
|
## Act 1 Summary
|
||||||
|
|
||||||
|
- User clarified credibility priority: SME understanding > measurable business value > modern UX/coding impression.
|
||||||
|
- User clarified homepage must be company-site quality, not a one-page landing page.
|
||||||
|
- User clarified visual direction: subtle macOS-inspired liquid glass, hybrid light/dark rhythm, abstract business-map parallax, restrained motion.
|
||||||
|
- User clarified implementation preference: Astro static + vanilla JS first, Google Apps Script for low-volume lead handling.
|
||||||
|
- User clarified CTA wording: use "ปรึกษาฟรี" only, not "ปรึกษาฟรี 30 นาที".
|
||||||
|
- User clarified Dealplustech must be included in portfolio using a homepage screenshot.
|
||||||
|
- User requested a copy-ready Google Apps Script file plus detailed setup instructions.
|
||||||
|
|
||||||
|
## Act 2 Status
|
||||||
|
|
||||||
|
Not started.
|
||||||
|
|
||||||
|
No implementation has been done from this plan yet.
|
||||||
351
PLAN.md
Normal file
@@ -0,0 +1,351 @@
|
|||||||
|
# Plan: MoreminiMore Homepage Rebuild
|
||||||
|
|
||||||
|
_Locked via grill — by Codex + Kunthawat_
|
||||||
|
|
||||||
|
## Goal
|
||||||
|
|
||||||
|
Rebuild the MoreminiMore company website from a clean slate, starting with the homepage only. The homepage must make SME owners feel that MoreminiMore is a friendly growth partner who understands real business problems, uses real data before recommending work, and can deliver modern, trustworthy websites and systems. The visual experience should feel modern and a little wow through restrained liquid-glass UI, layered parallax, and polished UX, but never become an effect demo or a tech showcase.
|
||||||
|
|
||||||
|
## Core Positioning
|
||||||
|
|
||||||
|
Priority of trust:
|
||||||
|
|
||||||
|
1. MoreminiMore understands SME businesses and their real problems.
|
||||||
|
2. MoreminiMore can help clients choose work that is more efficient, worthwhile, and suitable for their business.
|
||||||
|
3. MoreminiMore writes modern code in the UX sense: smooth, beautiful, easy to use, and subtly impressive.
|
||||||
|
|
||||||
|
Target customer priority:
|
||||||
|
|
||||||
|
1. Businesses that already have a website, ads, or tools, but feel the result is not worth the money or effort.
|
||||||
|
2. Businesses that do not yet have a good website or system and want to start correctly.
|
||||||
|
3. Businesses growing into AI/automation/workflow needs.
|
||||||
|
|
||||||
|
Brand role:
|
||||||
|
|
||||||
|
1. Growth partner for SMEs.
|
||||||
|
2. Business diagnosis partner.
|
||||||
|
3. Team that can implement real working solutions.
|
||||||
|
|
||||||
|
Tone:
|
||||||
|
|
||||||
|
- Friendly-first.
|
||||||
|
- Thai-first copy.
|
||||||
|
- English only for service names and necessary terms.
|
||||||
|
- No consultant-speak, no overly technical language, no fake metrics.
|
||||||
|
|
||||||
|
## Homepage Strategy
|
||||||
|
|
||||||
|
Hero strategy:
|
||||||
|
|
||||||
|
- Belief-led headline.
|
||||||
|
- Pain-led subheadline.
|
||||||
|
- Promise-led CTA/context.
|
||||||
|
|
||||||
|
Current hero copy direction:
|
||||||
|
|
||||||
|
> ธุรกิจไม่ควรเสียเงินกับสิ่งที่ยังไม่รู้ว่าคุ้มไหม
|
||||||
|
>
|
||||||
|
> เราช่วย SME ดูข้อมูลจริงก่อนตัดสินใจทำเว็บ การตลาด AI หรือระบบอัตโนมัติ เพื่อเลือกสิ่งที่ควรทำ อย่างมีประสิทธิภาพ และเหมาะสมกับลูกค้า
|
||||||
|
|
||||||
|
The final copy can be polished, especially the phrase "เหมาะสมกับลูกค้า", but the idea should stay intact.
|
||||||
|
|
||||||
|
Primary conversion priority:
|
||||||
|
|
||||||
|
1. ส่งโจทย์ธุรกิจให้เราดูก่อน
|
||||||
|
2. ดูเคส/ผลงานก่อน แล้วค่อยติดต่อ
|
||||||
|
3. ปรึกษาฟรี
|
||||||
|
|
||||||
|
Do not use "30 นาที" in CTA copy. Use "ปรึกษาฟรี" only.
|
||||||
|
|
||||||
|
Homepage v1 must not include a blog section. Blog content can stay preserved for later, but the homepage should focus on trust, diagnosis, proof, service clarity, portfolio quality, and conversion.
|
||||||
|
|
||||||
|
## Homepage Sections
|
||||||
|
|
||||||
|
Recommended homepage order:
|
||||||
|
|
||||||
|
1. Hero
|
||||||
|
- Belief-led headline.
|
||||||
|
- Friendly explanation.
|
||||||
|
- CTA to open problem form.
|
||||||
|
- Light abstract business-map background with subtle liquid glass.
|
||||||
|
|
||||||
|
2. Problem framing
|
||||||
|
- Explain that customers do not need to know which service they need.
|
||||||
|
- MoreminiMore will map the problem to the suitable service.
|
||||||
|
- CTA opens the same slide-over form.
|
||||||
|
|
||||||
|
3. Dataroot diagnosis story
|
||||||
|
- Dark diagnosis stage.
|
||||||
|
- Split case layout.
|
||||||
|
- Left side: narrative diagnosis.
|
||||||
|
- Right side: metric cards and relevant visual/screenshot.
|
||||||
|
- Use only real Dataroot metrics:
|
||||||
|
- +373% impression
|
||||||
|
- +114.2% click
|
||||||
|
- -28.3% ad spend
|
||||||
|
|
||||||
|
4. Outcome-first service cards
|
||||||
|
- Service name is still visible in English.
|
||||||
|
- Card headline should sell the outcome/problem solved, not the service label first.
|
||||||
|
- Desktop hover reveals "เหมาะกับปัญหาแบบไหน".
|
||||||
|
- Mobile shows essential information directly.
|
||||||
|
|
||||||
|
5. Portfolio preview
|
||||||
|
- Dark gallery stage.
|
||||||
|
- Featured + grid layout.
|
||||||
|
- Featured 1 should be Jet Industries for credibility.
|
||||||
|
- Featured 2 should be selected from the most visually strong portfolio screenshot after inspecting assets.
|
||||||
|
- Dataroot does not need to be the main portfolio feature because it has the diagnosis story.
|
||||||
|
- Portfolio role is mainly visual website quality, because most clients are website clients.
|
||||||
|
|
||||||
|
6. Mini process
|
||||||
|
- Short 4-step process:
|
||||||
|
1. เข้าใจธุรกิจ
|
||||||
|
2. ดูข้อมูล
|
||||||
|
3. เลือกทางที่คุ้ม
|
||||||
|
4. ลงมือและวัดผล
|
||||||
|
|
||||||
|
7. Final CTA
|
||||||
|
- Friendly, low-friction.
|
||||||
|
- Reopen form panel.
|
||||||
|
- Reinforce "ส่งโจทย์ให้เราดูก่อน".
|
||||||
|
|
||||||
|
## Problem Form
|
||||||
|
|
||||||
|
The primary CTA opens a form, not a separate contact page.
|
||||||
|
|
||||||
|
Placement and behavior:
|
||||||
|
|
||||||
|
- Desktop: glass slide-over panel from the right.
|
||||||
|
- Mobile: bottom sheet.
|
||||||
|
- Floating/sticky CTA appears after the hero, not immediately on first paint.
|
||||||
|
- Navigation also has a CTA.
|
||||||
|
|
||||||
|
Problem chips:
|
||||||
|
|
||||||
|
1. เว็บมีอยู่แล้ว แต่ไม่ค่อยมีลูกค้าทัก
|
||||||
|
2. ยิงแอดอยู่ แต่ยอดขายไม่คุ้ม
|
||||||
|
3. มีคนทักมา แต่ไม่ใช่ลูกค้าที่ใช่
|
||||||
|
4. ทีมงานทำงานเดิม ๆ แต่ทำงานช้า หรือผิดพลาดบ่อย
|
||||||
|
5. อยากใช้ AI แต่ไม่รู้เริ่มตรงไหน
|
||||||
|
6. ยังไม่แน่ใจว่าควรแก้อะไรก่อน
|
||||||
|
|
||||||
|
Textarea:
|
||||||
|
|
||||||
|
- Must include a very short example because customers are assumed to be lazy and may not want to type.
|
||||||
|
- Example direction:
|
||||||
|
- "ยิงแอดอยู่ แต่ยอดขายไม่คุ้ม อยากรู้ว่าควรแก้อะไรก่อน"
|
||||||
|
- "มีเว็บแล้ว แต่ลูกค้าไม่ค่อยทัก อยากรู้ว่าควรแก้เว็บหรือยิงแอดก่อน"
|
||||||
|
|
||||||
|
Contact fields:
|
||||||
|
|
||||||
|
- Name.
|
||||||
|
- Phone.
|
||||||
|
- Email.
|
||||||
|
- Phone or email must be provided, but both are not required.
|
||||||
|
- Labels must be explicit because non-technical customers may be confused by a single generic "contact channel" field.
|
||||||
|
|
||||||
|
Submission backend:
|
||||||
|
|
||||||
|
- Use Google Apps Script first because lead volume is expected to be low.
|
||||||
|
- Send notification email to Gmail/Google Workspace.
|
||||||
|
- Ideally also store leads in Google Sheet.
|
||||||
|
- Sender should be MoreminiMore-owned; customer contact should be used as reply-to where possible.
|
||||||
|
- Keep message clean to reduce spam risk.
|
||||||
|
- Provide the Google Apps Script as a copy-ready file because the user has not done this setup before.
|
||||||
|
- Current script artifact: `google-apps-script/lead-form.gs`.
|
||||||
|
- Current setup guide: `google-apps-script/SETUP.md`.
|
||||||
|
|
||||||
|
Post-submit UX:
|
||||||
|
|
||||||
|
- Stay in the panel.
|
||||||
|
- Show success message plus light diagnosis preview.
|
||||||
|
- Do not pretend to generate a complete diagnosis.
|
||||||
|
- Example direction: "จากปัญหาที่เลือก เราน่าจะเริ่มจากการดูเว็บ/แอด/ขั้นตอนทำงานก่อน แล้วจะติดต่อกลับทางเบอร์หรืออีเมลที่ให้ไว้"
|
||||||
|
|
||||||
|
## Navigation
|
||||||
|
|
||||||
|
This is a company website, not a one-page landing page.
|
||||||
|
|
||||||
|
Navigation should include:
|
||||||
|
|
||||||
|
- หน้าแรก
|
||||||
|
- บริการ
|
||||||
|
- ผลงาน
|
||||||
|
- เกี่ยวกับ
|
||||||
|
- FAQ and/or บทความ
|
||||||
|
- ติดต่อ / ส่งโจทย์ให้เราดู
|
||||||
|
|
||||||
|
Services submenu:
|
||||||
|
|
||||||
|
- Compact mega menu.
|
||||||
|
- Use English service names:
|
||||||
|
- Website Development
|
||||||
|
- Marketing Consult
|
||||||
|
- Automation Workflow
|
||||||
|
- AI Consult
|
||||||
|
- Include a short Thai explanation under each service name.
|
||||||
|
- Desktop supports hover, click, and keyboard.
|
||||||
|
- Mobile uses an accordion/list.
|
||||||
|
|
||||||
|
Nav visual behavior:
|
||||||
|
|
||||||
|
- Hybrid glass sticky nav.
|
||||||
|
- On hero: transparent/light glass.
|
||||||
|
- After scroll: compact stronger glass/solid for readability.
|
||||||
|
|
||||||
|
## Visual System
|
||||||
|
|
||||||
|
Overall mode:
|
||||||
|
|
||||||
|
- Hybrid light/dark.
|
||||||
|
- Light glass for friendly SME trust.
|
||||||
|
- Dark/premium stages for Dataroot diagnosis and portfolio.
|
||||||
|
|
||||||
|
Section atmosphere:
|
||||||
|
|
||||||
|
- Light hero.
|
||||||
|
- Dark Dataroot diagnosis.
|
||||||
|
- Light service/process/form context.
|
||||||
|
- Dark portfolio gallery.
|
||||||
|
|
||||||
|
Brand assets:
|
||||||
|
|
||||||
|
- Use existing logo.
|
||||||
|
- Use `#fed400` as accent only, not as a full-page wash.
|
||||||
|
- Use red `#d4553a` sparingly if useful.
|
||||||
|
- Avoid recreating the old yellow-heavy design.
|
||||||
|
|
||||||
|
Liquid glass:
|
||||||
|
|
||||||
|
- Subtle macOS-inspired.
|
||||||
|
- Use in key moments only:
|
||||||
|
- Navigation.
|
||||||
|
- CTA/form slide-over.
|
||||||
|
- Hero card/form/selected elements.
|
||||||
|
- Dataroot diagnosis cards.
|
||||||
|
- Possibly light service cards, but not every surface.
|
||||||
|
- Must preserve readability before effect.
|
||||||
|
|
||||||
|
Background and parallax:
|
||||||
|
|
||||||
|
- Main background concept: abstract business map.
|
||||||
|
- Use lines, nodes, soft grids, flow paths, and layered decision-map visuals.
|
||||||
|
- Hero should not rely on stock imagery.
|
||||||
|
- Portfolio sections can use real portfolio screenshots as the main visual material.
|
||||||
|
|
||||||
|
Motion:
|
||||||
|
|
||||||
|
- Desktop:
|
||||||
|
- Hero mouse parallax should be noticeable enough to feel dimensional.
|
||||||
|
- Scroll-driven scene changes are allowed.
|
||||||
|
- Use exactly 3 main background scenes:
|
||||||
|
1. Hero / light business map.
|
||||||
|
2. Dataroot / dark diagnosis stage.
|
||||||
|
3. Portfolio / dark gallery stage.
|
||||||
|
- Mobile:
|
||||||
|
- No mouse interaction.
|
||||||
|
- Use scroll parallax/reveal only.
|
||||||
|
- Keep performance conservative.
|
||||||
|
|
||||||
|
## Portfolio Rules
|
||||||
|
|
||||||
|
Portfolio role:
|
||||||
|
|
||||||
|
- Show website visual quality and execution.
|
||||||
|
- Most clients are website clients, not consulting clients.
|
||||||
|
- Consulting-heavy proof is mainly Dataroot.
|
||||||
|
- Dealplustech must be included in the website portfolio.
|
||||||
|
- URL: `https://www.dealplustech.co.th`
|
||||||
|
- Capture a homepage screenshot and use it as a portfolio image, matching the treatment of other portfolio clients.
|
||||||
|
- Dealplustech is both website work and consulting-adjacent, but should still appear as a website portfolio item.
|
||||||
|
|
||||||
|
Client context:
|
||||||
|
|
||||||
|
- Largest client: Jet Industries.
|
||||||
|
- Second largest: Dataroot.
|
||||||
|
- Most other clients are smaller.
|
||||||
|
|
||||||
|
Sorting priority:
|
||||||
|
|
||||||
|
1. Visual quality / modern feel.
|
||||||
|
2. Professional credibility.
|
||||||
|
3. SME relatability.
|
||||||
|
|
||||||
|
Featured portfolio:
|
||||||
|
|
||||||
|
- Featured 1: Jet Industries.
|
||||||
|
- Featured 2: choose visually strongest work after inspecting assets.
|
||||||
|
- Other projects in grid.
|
||||||
|
|
||||||
|
## Technical Approach
|
||||||
|
|
||||||
|
Stack:
|
||||||
|
|
||||||
|
- Astro static, rebuilt from scratch.
|
||||||
|
- Vanilla JS first.
|
||||||
|
- CSS first for liquid glass and layout.
|
||||||
|
- Use small vanilla scripts for:
|
||||||
|
- Mouse parallax.
|
||||||
|
- Scroll scene transitions.
|
||||||
|
- Slide-over/bottom sheet form.
|
||||||
|
- Form validation and submission.
|
||||||
|
- Do not use React by default.
|
||||||
|
- Add React only if a specific interaction becomes too complex for readable vanilla JS.
|
||||||
|
|
||||||
|
Implementation scope:
|
||||||
|
|
||||||
|
- Homepage-first.
|
||||||
|
- Do not build full route details in v1.
|
||||||
|
- Navigation may reference future routes, but implementation focus is homepage.
|
||||||
|
- Preserve extracted inputs in `redesign-input/`.
|
||||||
|
- Old code remains archived in `_archive/pre-redesign-2026-06-21/`.
|
||||||
|
|
||||||
|
Suggested initial implementation files after plan approval:
|
||||||
|
|
||||||
|
1. Recreate minimal Astro project files at root:
|
||||||
|
- `package.json`
|
||||||
|
- `astro.config.mjs`
|
||||||
|
- `tsconfig.json`
|
||||||
|
- `src/pages/index.astro`
|
||||||
|
- `src/styles/global.css`
|
||||||
|
- `src/scripts/home.js`
|
||||||
|
2. Copy required assets from `redesign-input/assets/` into `public/`.
|
||||||
|
3. Build homepage components either inline first or split only when repeated:
|
||||||
|
- Navigation
|
||||||
|
- Hero
|
||||||
|
- Problem CTA panel
|
||||||
|
- Dataroot case
|
||||||
|
- Service cards
|
||||||
|
- Portfolio preview
|
||||||
|
- Process
|
||||||
|
- Footer
|
||||||
|
4. Add Google Apps Script endpoint configuration as an environment/runtime variable if possible.
|
||||||
|
|
||||||
|
## Key Decisions & Tradeoffs
|
||||||
|
|
||||||
|
- Problem-first homepage, but service cards still exist because this is a company website.
|
||||||
|
- Friendly-first copy, but visual system must remain premium enough for Jet/Dataroot credibility.
|
||||||
|
- Use English service names in nav for professionalism, but Thai copy everywhere else for clarity.
|
||||||
|
- Use Google Apps Script before heavier transactional email infrastructure because lead volume is expected to be low.
|
||||||
|
- Use Astro static + vanilla JS to keep the site light and maintainable.
|
||||||
|
- Use effects only in high-impact places to avoid repeating the previous failure mode of design overwhelming the business message.
|
||||||
|
|
||||||
|
## Risks / Open Questions
|
||||||
|
|
||||||
|
- The exact visual quality of portfolio assets must be inspected before choosing Featured 2.
|
||||||
|
- Dealplustech needs a homepage screenshot before implementation can finalize portfolio assets.
|
||||||
|
- Google Apps Script deliverability depends on the Google account/domain setup. SPF/DKIM/DMARC should be checked before production.
|
||||||
|
- Navigation points to company-site routes, but homepage is the first implementation scope. Decide whether future routes should be placeholders, omitted, or added later.
|
||||||
|
- Need final decision on exact final hero copy during implementation polish.
|
||||||
|
|
||||||
|
## Out Of Scope For Homepage V1
|
||||||
|
|
||||||
|
- Full services pages.
|
||||||
|
- Full portfolio detail pages.
|
||||||
|
- Blog section on homepage.
|
||||||
|
- Full blog redesign.
|
||||||
|
- Heavy WebGL/canvas animation.
|
||||||
|
- Full React app or SPA rewrite.
|
||||||
|
- Invented metrics or testimonials.
|
||||||
|
- Reusing old design or old code structure as the main foundation.
|
||||||
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,166 +0,0 @@
|
|||||||
/**
|
|
||||||
* MOREMINIMORE - Contact Form Backend (Google Apps Script)
|
|
||||||
* Per plan 2026-06-13 round 2 #4:
|
|
||||||
* Form submit → Apps Script doPost() → Google Sheet (log)
|
|
||||||
* → Email to contact@moreminimore.com
|
|
||||||
* → LINE Notify
|
|
||||||
*
|
|
||||||
* USER DEPLOYS THIS THEMSELVES (see README.md in same folder).
|
|
||||||
* 1. Create new Apps Script project at https://script.google.com
|
|
||||||
* 2. Paste this entire file into Code.gs
|
|
||||||
* 3. Set Script Properties (Project Settings → Script Properties):
|
|
||||||
* SHEET_ID — Google Sheet ID (from Sheet URL)
|
|
||||||
* LINE_NOTIFY_TOKEN — from https://notify-bot.line.me
|
|
||||||
* RECIPIENT_EMAIL — contact@moreminimore.com (or any email)
|
|
||||||
* 4. Create Google Sheet with these headers in row 1:
|
|
||||||
* timestamp | name | phone | email | service | message | variant | userAgent
|
|
||||||
* 5. Deploy → New deployment → Type: Web app
|
|
||||||
* Execute as: Me
|
|
||||||
* Who has access: Anyone
|
|
||||||
* Copy the deployment URL.
|
|
||||||
* 6. Add to moreminimore-astroreal/.env:
|
|
||||||
* PUBLIC_CONTACT_ENDPOINT=<paste deployment URL>
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------ */
|
|
||||||
/* CONFIG — read from Script Properties (set in Project Settings) */
|
|
||||||
/* ------------------------------------------------------------------ */
|
|
||||||
|
|
||||||
function getConfig() {
|
|
||||||
const props = PropertiesService.getScriptProperties();
|
|
||||||
return {
|
|
||||||
SHEET_ID: props.getProperty('SHEET_ID'),
|
|
||||||
LINE_NOTIFY_TOKEN: props.getProperty('LINE_NOTIFY_TOKEN'),
|
|
||||||
RECIPIENT_EMAIL: props.getProperty('RECIPIENT_EMAIL') || 'contact@moreminimore.com',
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------ */
|
|
||||||
/* HANDLER — POST /exec (or /dev) */
|
|
||||||
/* ------------------------------------------------------------------ */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle form submission. Expects JSON body:
|
|
||||||
* {
|
|
||||||
* name, phone, email, service, message, variant, userAgent, submittedAt
|
|
||||||
* }
|
|
||||||
*/
|
|
||||||
function doPost(e) {
|
|
||||||
try {
|
|
||||||
const data = JSON.parse(e.postData.contents);
|
|
||||||
const config = getConfig();
|
|
||||||
|
|
||||||
// 1. Log to Google Sheet
|
|
||||||
let rowId = null;
|
|
||||||
if (config.SHEET_ID) {
|
|
||||||
const sheet = SpreadsheetApp.openById(config.SHEET_ID).getActiveSheet();
|
|
||||||
const row = sheet.appendRow([
|
|
||||||
new Date(), // timestamp
|
|
||||||
data.name || '',
|
|
||||||
data.phone || '',
|
|
||||||
data.email || '',
|
|
||||||
data.service || '',
|
|
||||||
data.message || '',
|
|
||||||
data.variant || 'full',
|
|
||||||
data.userAgent || '',
|
|
||||||
]);
|
|
||||||
rowId = row.getRange().getRow();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2. Send email
|
|
||||||
const subject = `[moreminimore contact] ${data.service || 'general'} — ${data.name || data.phone || 'unknown'}`;
|
|
||||||
const body = formatEmailBody(data);
|
|
||||||
MailApp.sendEmail({
|
|
||||||
to: config.RECIPIENT_EMAIL,
|
|
||||||
subject: subject,
|
|
||||||
body: body,
|
|
||||||
replyTo: data.email || undefined,
|
|
||||||
});
|
|
||||||
|
|
||||||
// 3. Send LINE Notify
|
|
||||||
if (config.LINE_NOTIFY_TOKEN) {
|
|
||||||
const lineMessage = formatLineMessage(data);
|
|
||||||
UrlFetchApp.fetch('https://notify-api.line.me/api/notify', {
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
'Authorization': 'Bearer ' + config.LINE_NOTIFY_TOKEN,
|
|
||||||
'Content-Type': 'application/x-www-form-urlencoded',
|
|
||||||
},
|
|
||||||
payload: { message: lineMessage },
|
|
||||||
muteHttpExceptions: true,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return ContentService
|
|
||||||
.createTextOutput(JSON.stringify({ ok: true, id: rowId }))
|
|
||||||
.setMimeType(ContentService.MimeType.JSON);
|
|
||||||
|
|
||||||
} catch (err) {
|
|
||||||
return ContentService
|
|
||||||
.createTextOutput(JSON.stringify({ ok: false, error: err.toString() }))
|
|
||||||
.setMimeType(ContentService.MimeType.JSON);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------ */
|
|
||||||
/* FORMATTERS */
|
|
||||||
/* ------------------------------------------------------------------ */
|
|
||||||
|
|
||||||
function formatEmailBody(data) {
|
|
||||||
return [
|
|
||||||
'New contact form submission',
|
|
||||||
'',
|
|
||||||
'---',
|
|
||||||
'Name: ' + (data.name || '-'),
|
|
||||||
'Phone: ' + (data.phone || '-'),
|
|
||||||
'Email: ' + (data.email || '-'),
|
|
||||||
'Service: ' + (data.service || '-'),
|
|
||||||
'Variant: ' + (data.variant || 'full'),
|
|
||||||
'---',
|
|
||||||
'',
|
|
||||||
'Message:',
|
|
||||||
data.message || '(empty)',
|
|
||||||
'',
|
|
||||||
'---',
|
|
||||||
'Submitted: ' + (data.submittedAt || new Date().toISOString()),
|
|
||||||
'UserAgent: ' + (data.userAgent || 'unknown'),
|
|
||||||
].join('\n');
|
|
||||||
}
|
|
||||||
|
|
||||||
function formatLineMessage(data) {
|
|
||||||
const lines = [
|
|
||||||
'🔔 moreminimore contact',
|
|
||||||
'',
|
|
||||||
'👤 ' + (data.name || data.phone || 'unknown'),
|
|
||||||
'📞 ' + (data.phone || '-'),
|
|
||||||
'✉ ' + (data.email || '-'),
|
|
||||||
'🎯 ' + (data.service || 'general'),
|
|
||||||
];
|
|
||||||
if (data.message) {
|
|
||||||
lines.push('');
|
|
||||||
lines.push(data.message.length > 200 ? data.message.slice(0, 200) + '...' : data.message);
|
|
||||||
}
|
|
||||||
return lines.join('\n');
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------ */
|
|
||||||
/* TEST (optional — call testDoPost() from Apps Script editor) */
|
|
||||||
/* ------------------------------------------------------------------ */
|
|
||||||
|
|
||||||
function testDoPost() {
|
|
||||||
const mockEvent = {
|
|
||||||
postData: {
|
|
||||||
contents: JSON.stringify({
|
|
||||||
name: 'Test User',
|
|
||||||
phone: '080-123-4567',
|
|
||||||
email: 'test@example.com',
|
|
||||||
service: 'webdev',
|
|
||||||
message: 'This is a test message',
|
|
||||||
variant: 'full',
|
|
||||||
userAgent: 'test',
|
|
||||||
submittedAt: new Date().toISOString(),
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
Logger.log(doPost(mockEvent).getContent());
|
|
||||||
}
|
|
||||||
@@ -1,140 +0,0 @@
|
|||||||
# Contact Form Backend — Google Apps Script
|
|
||||||
|
|
||||||
This is the backend for the contact form on the MoreminiMore website.
|
|
||||||
|
|
||||||
When someone submits the form, this Apps Script:
|
|
||||||
1. **Logs** the submission to a Google Sheet (audit trail)
|
|
||||||
2. **Emails** the submission to `contact@moreminimore.com` (your Google Workspace)
|
|
||||||
3. **Sends** a LINE Notify to your phone
|
|
||||||
|
|
||||||
The user (you) deploys this script. Hermes Agent cannot deploy it for you — it requires access to your Google account.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Prerequisites
|
|
||||||
|
|
||||||
- A Google account (use `contact@moreminimore.com` or any Google Workspace account)
|
|
||||||
- A LINE Notify token (get one at <https://notify-bot.line.me/> — log in → My page → Generate token)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Setup (5 minutes)
|
|
||||||
|
|
||||||
### Step 1: Create the Apps Script project
|
|
||||||
|
|
||||||
1. Go to <https://script.google.com/start>
|
|
||||||
2. Click **New project** (or "โปรเจ็กต์ใหม่" in Thai)
|
|
||||||
3. Rename the project (top-left) to `moreminimore-contact-form`
|
|
||||||
4. Delete the default `function myFunction() {}` code
|
|
||||||
5. Open `Code.gs` from this folder in your text editor
|
|
||||||
6. **Copy the entire contents** and **paste** into the Apps Script editor
|
|
||||||
7. Click 💾 (Save) or Ctrl+S
|
|
||||||
|
|
||||||
### Step 2: Set Script Properties
|
|
||||||
|
|
||||||
1. Click **Project Settings** (⚙️ gear icon on the left)
|
|
||||||
2. Scroll down to **Script Properties**
|
|
||||||
3. Click **Add script property** and add these 3:
|
|
||||||
|
|
||||||
| Property | Value | Where to get it |
|
|
||||||
|---|---|---|
|
|
||||||
| `SHEET_ID` | (Google Sheet ID) | See Step 3 below |
|
|
||||||
| `LINE_NOTIFY_TOKEN` | (LINE token) | <https://notify-bot.line.me/> → My page → Generate token → Copy |
|
|
||||||
| `RECIPIENT_EMAIL` | `contact@moreminimore.com` | Just type your email |
|
|
||||||
|
|
||||||
### Step 3: Create the Google Sheet
|
|
||||||
|
|
||||||
1. Go to <https://sheets.google.com/create>
|
|
||||||
2. Rename to `moreminimore-contact-log` (or whatever you like)
|
|
||||||
3. In row 1, add these headers (one per cell, A1 through H1):
|
|
||||||
```
|
|
||||||
timestamp | name | phone | email | service | message | variant | userAgent
|
|
||||||
```
|
|
||||||
4. **Get the Sheet ID** from the URL:
|
|
||||||
- URL looks like: `https://docs.google.com/spreadsheets/d/1aBcD...XyZ/edit`
|
|
||||||
- The `1aBcD...XyZ` part is the **SHEET_ID** — copy it
|
|
||||||
5. Paste it into Script Properties → `SHEET_ID` value
|
|
||||||
|
|
||||||
### Step 4: Test the script (optional but recommended)
|
|
||||||
|
|
||||||
1. In the Apps Script editor, select function `testDoPost` from the dropdown (next to the debug ▶ button)
|
|
||||||
2. Click **Run** (▶)
|
|
||||||
3. If prompted, authorize the script (review permissions → Allow)
|
|
||||||
4. Check:
|
|
||||||
- The Google Sheet has a new row at the bottom
|
|
||||||
- The recipient email got a new message
|
|
||||||
- Your LINE got a notification
|
|
||||||
5. Check **Execution log** (View → Logs) for any errors
|
|
||||||
|
|
||||||
### Step 5: Deploy as Web App
|
|
||||||
|
|
||||||
1. Click **Deploy** (top-right) → **New deployment**
|
|
||||||
2. Click the ⚙️ gear icon → select **Web app**
|
|
||||||
3. Configure:
|
|
||||||
- **Description**: `moreminimore contact form v1`
|
|
||||||
- **Execute as**: `Me (your-email@gmail.com)`
|
|
||||||
- **Who has access**: `Anyone` ← important, otherwise form can't reach it
|
|
||||||
4. Click **Deploy**
|
|
||||||
5. You may be asked to authorize again — click **Review permissions** → choose your account → **Allow**
|
|
||||||
6. **Copy the Web app URL** — it looks like:
|
|
||||||
```
|
|
||||||
https://script.google.com/macros/s/AKfycbz.../exec
|
|
||||||
```
|
|
||||||
|
|
||||||
### Step 6: Wire the URL into the website
|
|
||||||
|
|
||||||
1. Open `moreminimore-astroreal/.env` (create it if it doesn't exist)
|
|
||||||
2. Add this line (paste your URL):
|
|
||||||
```
|
|
||||||
PUBLIC_CONTACT_ENDPOINT=https://script.google.com/macros/s/AKfycbz.../exec
|
|
||||||
```
|
|
||||||
3. Save the file
|
|
||||||
4. Rebuild the site: `npm run build`
|
|
||||||
5. Deploy (or push to your host)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Verifying it works
|
|
||||||
|
|
||||||
After deploy, visit the website, fill the form, hit submit.
|
|
||||||
|
|
||||||
You should see:
|
|
||||||
- ✅ Toast: "✓ ส่งแล้ว เราจะติดต่อกลับภายใน 24 ชม."
|
|
||||||
- ✅ New row in the Google Sheet
|
|
||||||
- ✅ Email in your inbox
|
|
||||||
- ✅ LINE notification on your phone
|
|
||||||
|
|
||||||
If something fails, check:
|
|
||||||
- **Apps Script Execution Log** (Executions tab on the left) — shows errors
|
|
||||||
- **Sheet ID** is correct (no extra spaces, full ID)
|
|
||||||
- **LINE token** is active (revoke + regenerate if needed)
|
|
||||||
- **"Who has access"** is set to `Anyone` on the deployment
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Updating the script later
|
|
||||||
|
|
||||||
When you change `Code.gs`:
|
|
||||||
1. Save in the editor
|
|
||||||
2. **Deploy** → **Manage deployments** → ✏️ (edit) → **Version: New version** → **Deploy**
|
|
||||||
3. The Web app URL stays the same — no need to update `.env`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Security notes
|
|
||||||
|
|
||||||
- The web app URL is not secret — anyone who knows it can submit
|
|
||||||
- But it has no destructive power (only appends rows + sends email/notify to you)
|
|
||||||
- If you receive spam, you can revoke the LINE token + change the deployment URL
|
|
||||||
- Consider adding reCAPTCHA later if spam becomes a problem
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Cost
|
|
||||||
|
|
||||||
- **Google Apps Script**: free (1-hour quota, plenty for contact forms)
|
|
||||||
- **Google Sheets**: free up to 10M cells
|
|
||||||
- **MailApp**: free for ~100 emails/day per user
|
|
||||||
- **LINE Notify**: free, unlimited messages, but discontinued March 2025 in some regions — check status at <https://notify-bot.line.me/>
|
|
||||||
|
|
||||||
If LINE Notify is shut down, swap the LINE call for a Telegram bot or Discord webhook (same `UrlFetchApp.fetch` pattern).
|
|
||||||
@@ -1,15 +1,8 @@
|
|||||||
// @ts-check
|
// @ts-check
|
||||||
import { defineConfig } from 'astro/config';
|
import { defineConfig } from 'astro/config';
|
||||||
import react from "@astrojs/react";
|
|
||||||
import mdx from "@astrojs/mdx";
|
|
||||||
|
|
||||||
// All content is markdown → static output. No server runtime needed.
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
output: "static",
|
output: 'static',
|
||||||
integrations: [
|
image: { layout: 'constrained', responsiveStyles: true },
|
||||||
react(),
|
devToolbar: { enabled: false },
|
||||||
mdx(),
|
|
||||||
],
|
|
||||||
image: { layout: "constrained", responsiveStyles: true },
|
|
||||||
devToolbar: { enabled: true },
|
|
||||||
});
|
});
|
||||||
|
|||||||
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);
|
||||||
|
}
|
||||||
6122
package-lock.json
generated
@@ -1,7 +1,8 @@
|
|||||||
{
|
{
|
||||||
"name": "moreminimore-site",
|
"name": "moreminimore-site",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"version": "0.0.1",
|
"version": "1.0.0",
|
||||||
|
"private": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=22.12.0"
|
"node": ">=22.12.0"
|
||||||
},
|
},
|
||||||
@@ -12,10 +13,6 @@
|
|||||||
"astro": "astro"
|
"astro": "astro"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@astrojs/mdx": "^5.0.6",
|
"astro": "^6.2.2"
|
||||||
"@astrojs/react": "^5.0.5",
|
|
||||||
"astro": "^6.2.2",
|
|
||||||
"react": "^19.2.5",
|
|
||||||
"react-dom": "^19.2.5"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 5.5 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 5.2 KiB |
|
Before Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 1.9 KiB |
@@ -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 |
|
Before Width: | Height: | Size: 28 KiB 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 |
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 |
|
Before Width: | Height: | Size: 23 KiB |
@@ -1,22 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "MoreminiMore",
|
|
||||||
"short_name": "MoreminiMore",
|
|
||||||
"description": "ที่ปรึกษาที่วางกลยุทธ์จากข้อมูล ไม่ใช่จากประสบการณ์ล้วน ๆ — รับทำเว็บ ที่ปรึกษาการตลาด และวางระบบ AI ในองค์กร",
|
|
||||||
"icons": [
|
|
||||||
{
|
|
||||||
"src": "/android-chrome-192x192.png",
|
|
||||||
"sizes": "192x192",
|
|
||||||
"type": "image/png"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"src": "/android-chrome-512x512.png",
|
|
||||||
"sizes": "512x512",
|
|
||||||
"type": "image/png"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"theme_color": "#fed400",
|
|
||||||
"background_color": "#ffffff",
|
|
||||||
"display": "standalone",
|
|
||||||
"start_url": "/",
|
|
||||||
"lang": "th"
|
|
||||||
}
|
|
||||||
@@ -1,277 +0,0 @@
|
|||||||
# คำถามสำหรับปรับปรุงเนื้อหาเว็บ moreminimore
|
|
||||||
|
|
||||||
> ตอบข้อไหนได้ก็ตอบ ข้อไหนไม่รู้หรือไม่อยากตอบก็เว้นว่างไว้
|
|
||||||
> พิมพ์สั้น ๆ ก็ได้ เช่น `A1: คนที่ทำเว็บแล้วดูแลต่อ ไม่ทิ้ง` — พอแล้ว เอาไปขยายต่อได้
|
|
||||||
>
|
|
||||||
> เมื่อเติมคำตอบเสร็จ ให้บอก path ของไฟล์นี้กลับมา เช่น `~/Desktop/questions-for-content.md` หรือ `moreminimore-astroreal/questions-for-content.md` หลัง `git push`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🔴 กลุ่ม A — ตัวตน & ตลาด (ตอบก่อนแตะปากกา)
|
|
||||||
|
|
||||||
เรื่องพื้นฐานที่ต้องชัดก่อนเขียนอะไร — ถ้าตอบไม่ได้สักข้อ ก็เป็นสัญญาณว่าเว็บยังเขียนไม่ได้
|
|
||||||
|
|
||||||
### A1 — คุณเป็นใครในมุมของลูกค้า
|
|
||||||
ถ้าเพื่อนที่เป็น SME ถามว่า "ทำไมต้องจ้างมอร์มินิมอร์ ทั้ง ๆ ที่มีตัวเลือกเยอะ" คุณตอบยังไงใน 1 ประโยค? (ไม่ใช่ประวัติ — เป็นสิ่งที่ทำให้คุณต่าง)
|
|
||||||
|
|
||||||
```
|
|
||||||
คำตอบ:
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
### A2 — ลูกค้าที่คุณชอบทำงานด้วยที่สุด
|
|
||||||
เป็นแบบไหน? (ขนาด, อุตสาหกรรม, ลักษณะนิสัย, งบประมาณคร่าว ๆ)
|
|
||||||
|
|
||||||
```
|
|
||||||
คำตอบ:
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
### A3 — ลูกค้าที่คุณไม่อยากรับ
|
|
||||||
เป็นแบบไหน? (จะเอาไปเขียนเป็นส่วน "ไม่เหมาะกับ" ในเว็บ — ทำให้คนที่ใช่อยากคุยมากขึ้น และลดเคสที่เสียเวลา)
|
|
||||||
|
|
||||||
```
|
|
||||||
คำตอบ:
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
### A4 — งานชิ้นที่ภูมิใจที่สุด
|
|
||||||
ชิ้นไหน และทำไม? (จะกลายเป็น portfolio flagship — อาจเล่าแบบเจาะลึก 1 หน้าเต็ม)
|
|
||||||
|
|
||||||
```
|
|
||||||
คำตอบ:
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
### A5 — งานชิ้นที่พังหรือเกือบพัง
|
|
||||||
เกิดอะไรขึ้น แก้ยังไง? (เอาไปเล่าเป็นบทเรียน — แบบนี้ลูกค้าจะเชื่อถือมากกว่า "ผลงานสวยหมด" เพราะดูจริงใจ)
|
|
||||||
|
|
||||||
```
|
|
||||||
คำตอบ:
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
### A6 — SME ไทยทำพลาดเรื่องเดิมซ้ำ ๆ เรื่องอะไร
|
|
||||||
ช่วง 5 ปีที่ผ่านมา คุณเห็นอะไรซ้ำ ๆ? (คำตอบจะกลายเป็นเสียงของคุณในเว็บ + ไอเดียเขียน blog ได้อีกหลายเรื่อง)
|
|
||||||
|
|
||||||
```
|
|
||||||
คำตอบ:
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🟠 กลุ่ม B — เสนอคุณค่า (ตอบก่อนเขียน service page)
|
|
||||||
|
|
||||||
เพื่อให้ service page แต่ละหน้าไม่ซ้ำกัน และลูกค้าเห็นว่าต้องเลือกคุณยังไง
|
|
||||||
|
|
||||||
### B7 — บริการแต่ละตัวต่างกันตรงไหน
|
|
||||||
Web / Marketing / Automation / AI Consult — กระบวนการทำงานต่างกันยังไง? ไม่ใช่ "ส่งมอบอะไร" แต่ "ทำงานยังไง"
|
|
||||||
|
|
||||||
- **Web (Astro/WordPress)** — workflow เป็นยังไง กี่รอบ feedback ใช้ stack อะไร
|
|
||||||
```
|
|
||||||
คำตอบ:
|
|
||||||
```
|
|
||||||
|
|
||||||
- **Marketing** — ใช้ GA4 / Meta Pixel / SEO tools อะไร วัดผลยังไง
|
|
||||||
```
|
|
||||||
คำตอบ:
|
|
||||||
```
|
|
||||||
|
|
||||||
- **Automation** — ใช้ n8n / Make / Zapier / custom code เลือกยังไง
|
|
||||||
```
|
|
||||||
คำตอบ:
|
|
||||||
```
|
|
||||||
|
|
||||||
- **AI Consult** — ใช้ RAG / fine-tune / agent อะไร เหมาะกับ case ไหน
|
|
||||||
```
|
|
||||||
คำตอบ:
|
|
||||||
```
|
|
||||||
|
|
||||||
### B8 — ถ้าทำได้อย่างเดียว ควรเริ่มจากอะไร
|
|
||||||
ลูกค้ามีงบจำกัด ทำได้อย่างเดียว — อันไหนคุ้มสุด? (ตอบตรง ๆ ตามจริง ไม่ใช่คำตอบที่ขายดีที่สุด — ความจริงใจตรงนี้จะกลายเป็นเครื่องมือปิดการขาย)
|
|
||||||
|
|
||||||
```
|
|
||||||
คำตอบ:
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
### B9 — คิดค่าบริการยังไง
|
|
||||||
เหมาจ่าย / รายเดือน / เก็บตาม sprint / value-based? ช่วงราคาคร่าว ๆ ของแต่ละบริการ:
|
|
||||||
|
|
||||||
- **Web Development** — โปรเจกต์ทั่วไปอยู่ที่ ____ บาท
|
|
||||||
```
|
|
||||||
คำตอบ:
|
|
||||||
```
|
|
||||||
|
|
||||||
- **Marketing** — ค่า setup + รายเดือน
|
|
||||||
```
|
|
||||||
คำตอบ:
|
|
||||||
```
|
|
||||||
|
|
||||||
- **Automation** — ค่าพัฒนา + ค่าดูแล
|
|
||||||
```
|
|
||||||
คำตอบ:
|
|
||||||
```
|
|
||||||
|
|
||||||
- **AI Consult** — ค่า consult / ชั่วโมง / โปรเจกต์
|
|
||||||
```
|
|
||||||
คำตอบ:
|
|
||||||
```
|
|
||||||
|
|
||||||
### B10 — คำถาม 5 ข้อที่ถามลูกค้าในการคุยครั้งแรก
|
|
||||||
ตอนคุยกันครั้งแรก คุณถามอะไรบ้าง? (จะเอาไปใส่หน้า Contact เป็น "ก่อนคุย เตรียมคำตอบพวกนี้มา" — คนที่อ่านแล้วตอบได้ = lead ที่มีคุณภาพ)
|
|
||||||
|
|
||||||
```
|
|
||||||
คำตอบ:
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🟡 กลุ่ม C — ความน่าเชื่อถือ (ตอบก่อนเขียน About / Portfolio)
|
|
||||||
|
|
||||||
ทำให้ soloprenuer กลายเป็นข้อได้เปรียบ ไม่ใช่จุดอ่อน
|
|
||||||
|
|
||||||
### C11 — เบื้องหลังการทำงานจริง
|
|
||||||
นั่งทำที่ไหน ใช้เครื่องอะไร stack/workflow แบบไหน — เล่าแบบที่คนอ่านแล้วเห็นภาพ "คนคนนี้จริงจัง"
|
|
||||||
|
|
||||||
```
|
|
||||||
คำตอบ:
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
### C12 — คำพูดลูกค้าที่จำไม่ลืม
|
|
||||||
เคยมีลูกค้าพูดอะไรที่ทำให้คุณจำได้? (quote แบบนี้แพ้ portfolio 10 หน้า — ถ้ามีหลาย quote บอกมาหลาย ๆ อันได้)
|
|
||||||
|
|
||||||
```
|
|
||||||
คำตอบ:
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
### C13 — กำลังเรียนรู้ / ทดลองอะไรอยู่
|
|
||||||
เช่น RAG, GEO, AI agent workflow, automation platform ใหม่ ๆ — ทำให้เห็นว่าคุณยังเดินหน้า ไม่หยุดนิ่ง
|
|
||||||
|
|
||||||
```
|
|
||||||
คำตอบ:
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
### C14 — ตัวเลขจริง ๆ ตอนนี้
|
|
||||||
ไม่ต้องสวย แค่ให้ calibrate เสียงและระดับความกล้าในการ claim:
|
|
||||||
|
|
||||||
- ทำมากี่ปี
|
|
||||||
- ส่งมอบกี่โปรเจกต์
|
|
||||||
- ลูกค้าซ้ำกี่คน
|
|
||||||
- ราคาเฉลี่ยต่อโปรเจกต์
|
|
||||||
- (ไม่ต้องเอาลงเว็บ แค่บอกผม)
|
|
||||||
|
|
||||||
```
|
|
||||||
คำตอบ:
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🟢 กลุ่ม D — มุมมอง & เสียง (ตอบก่อนเขียนทุกหน้า)
|
|
||||||
|
|
||||||
เสียงที่จดจำได้ = มุมมองที่ชัด ไม่ใช่ถ้อยคำที่สวย
|
|
||||||
|
|
||||||
### D15 — เรื่องที่ไม่เห็นด้วยในวงการ
|
|
||||||
AI/Web agency ทำอะไรที่คุณคิดว่าผิด / เกินจำเป็น / หลอกลูกค้า? (ความเห็นต่าง = เสียงที่จดจำได้ เช่น "เราไม่เชื่อว่า SME ต้องมี chatbot ทุกเว็บ")
|
|
||||||
|
|
||||||
```
|
|
||||||
คำตอบ:
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
### D16 — 1 ประโยคที่อยากให้คนจำ
|
|
||||||
ถ้าเขียนเว็บได้แค่ 1 ประโยค อยากให้คนจำว่ามอร์มินิมอร์เป็นแบบไหน — ประโยคนั้นคืออะไร?
|
|
||||||
|
|
||||||
```
|
|
||||||
คำตอบ:
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
### D17 — โทนเสียงที่อยากให้เว็บเป็น
|
|
||||||
เลือก 1-2 ข้อ (หรือผสม):
|
|
||||||
|
|
||||||
- [ ] ตรง ๆ ดุ ๆ (เหมือนคุยกับเพื่อน)
|
|
||||||
- [ ] สุภาพ มืออาชีพ (เหมือนที่ปรึกษา)
|
|
||||||
- [ ] ขำ ๆ มีอารมณ์ขัน
|
|
||||||
- [ ] เน้นข้อมูล ไม่มีน้ำ
|
|
||||||
- [ ] เล่าเรื่อง เป็นกันเอง
|
|
||||||
- [ ] อื่น ๆ (บอกมา)
|
|
||||||
|
|
||||||
```
|
|
||||||
คำตอบ:
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
### D18 — เว็บที่ชอบ / vibe ที่อยากได้
|
|
||||||
เว็บคู่แข่ง หรือเว็บต่างประเทศที่ชอบ vibe คล้าย ๆ — ส่งลิงก์มากี่อันก็ได้ พร้อมเหตุผลสั้น ๆ ว่าชอบอะไร
|
|
||||||
|
|
||||||
```
|
|
||||||
คำตอบ:
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## หลังได้คำตอบแล้ว จะทำอะไรต่อ
|
|
||||||
|
|
||||||
1. สรุป "เสียงของแบรนด์" ใน 1 หน้า (ไม่เกิน 10 ข้อ)
|
|
||||||
2. เขียน portfolio แต่ละชิ้นใหม่ — format: `[ชื่อ]. [อุตสาหกรรม]. [ปัญหา]. [สิ่งที่ทำ]. [ตัวเลข]. [เวลา]`
|
|
||||||
3. เขียน Home page copy ใหม่ — ลด 12 problem cards เหลือ 3-4 ที่เจ็บที่สุด พร้อมเฉลย
|
|
||||||
4. เขียน Service pages ใหม่ แยกตามเสียงและกระบวนการจริง
|
|
||||||
5. เขียน About page ใหม่ ให้ soloprenuer กลายเป็นข้อได้เปรียบ
|
|
||||||
6. เขียน FAQ จากคำถามที่ลูกค้าถามบ่อยจริง ๆ
|
|
||||||
7. วางแผน Blog topics 5 เรื่อง จากคำตอบ A6 + D15
|
|
||||||
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`
|
||||||
BIN
redesign-input/assets/logos/logo-long-black.png
Normal file
|
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 |
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)
|
||||||