diff --git a/templates/marketing/package.json b/templates/marketing/package.json index 10ed7da..9638b51 100644 --- a/templates/marketing/package.json +++ b/templates/marketing/package.json @@ -1,6 +1,6 @@ { - "name": "@emdash-cms/template-marketing", - "version": "0.0.3", + "name": "moreminimore", + "version": "1.0.0", "private": true, "type": "module", "emdash": { @@ -18,13 +18,15 @@ "dependencies": { "@astrojs/node": "catalog:", "@astrojs/react": "catalog:", + "@moreminimore/consent": "file:./plugins/consent", "astro": "catalog:", "better-sqlite3": "catalog:", "emdash": "workspace:*", + "nodemailer": "^6.9.16", "react": "catalog:", "react-dom": "catalog:" }, "devDependencies": { "@astrojs/check": "catalog:" } -} +} \ No newline at end of file diff --git a/templates/marketing/src/pages/api/contact.ts b/templates/marketing/src/pages/api/contact.ts new file mode 100644 index 0000000..20df7ed --- /dev/null +++ b/templates/marketing/src/pages/api/contact.ts @@ -0,0 +1,216 @@ +import type { APIRoute } from "astro"; +import nodemailer from "nodemailer"; + +export const POST: APIRoute = async ({ request }) => { + try { + const data = await request.formData(); + + const name = data.get("name")?.toString().trim() || ""; + const email = data.get("email")?.toString().trim() || ""; + const phone = data.get("phone")?.toString().trim() || ""; + const service = data.get("service")?.toString().trim() || ""; + const message = data.get("message")?.toString().trim() || ""; + + // Validation + if (!name || !email || !message) { + return new Response( + JSON.stringify({ success: false, error: "กรุณากรอกข้อมูลให้ครบ" }), + { status: 400, headers: { "Content-Type": "application/json" } } + ); + } + + if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) { + return new Response( + JSON.stringify({ success: false, error: "รูปแบบอีเมลไม่ถูกต้อง" }), + { status: 400, headers: { "Content-Type": "application/json" } } + ); + } + + // Check SMTP config from environment + const smtpHost = import.meta.env.SMTP_HOST; + const smtpPort = import.meta.env.SMTP_PORT || "587"; + const smtpUser = import.meta.env.SMTP_USER; + const smtpPass = import.meta.env.SMTP_PASS; + const smtpFrom = import.meta.env.SMTP_FROM || "noreply@moreminimore.com"; + const toEmail = import.meta.env.CONTACT_EMAIL || "contact@moreminimore.com"; + + const serviceLabel: Record = { + "web-development": "Web Development", + "ai-automation": "AI Automation", + "marketing-automation": "Marketing Automation", + "tech-consult": "Tech Consult", + other: "อื่นๆ", + }; + + const htmlBody = ` + + + + + + + +
+
+

📬 มีข้อความใหม่จากเว็บไซต์

+
+
+
+
ชื่อ
+
${name}
+
+
+
อีเมล
+ +
+ ${phone ? ` +
+
เบอร์โทรศัพท์
+ +
` : ""} + ${service ? ` +
+
บริการที่สนใจ
+
${serviceLabel[service] || service}
+
` : ""} +
+
ข้อความ
+
+
${message.replace(//g, ">").replace(/\n/g, "
")}
+
+
+
+ +
+ +`; + + const textBody = ` +มีข้อความใหม่จากเว็บไซต์ + +ชื่อ: ${name} +อีเมล: ${email} +${phone ? `เบอร์โทร: ${phone}` : ""} +${service ? `บริการ: ${serviceLabel[service] || service}` : ""} + +ข้อความ: +${message} + +--- +ส่งเมื่อ: ${new Date().toLocaleString("th-TH", { timeZone: "Asia/Bangkok" })} +MoreminiMore +`; + + // Send email if SMTP is configured + if (smtpHost && smtpUser && smtpPass) { + const transporter = nodemailer.createTransport({ + host: smtpHost, + port: Number(smtpPort), + secure: Number(smtpPort) === 465, + auth: { + user: smtpUser, + pass: smtpPass, + }, + }); + + await transporter.sendMail({ + from: `"MoreminiMore Website" <${smtpFrom}>`, + to: toEmail, + replyTo: email, + subject: `📬 ข้อความใหม่จาก ${name}${service ? ` - ${serviceLabel[service] || service}` : ""}`, + text: textBody, + html: htmlBody, + }); + } + + // Auto-reply to sender + if (smtpHost && smtpUser && smtpPass) { + const transporter = nodemailer.createTransport({ + host: smtpHost, + port: Number(smtpPort), + secure: Number(smtpPort) === 465, + auth: { + user: smtpUser, + pass: smtpPass, + }, + }); + + await transporter.sendMail({ + from: `"MoreminiMore" <${smtpFrom}>`, + to: email, + subject: "📧 เราได้รับข้อความของคุณแล้ว", + html: ` + + + + + + + +
+
+

✨ ขอบคุณที่ติดต่อ MoreminiMore

+
+
+

สวัสดีคุณ ${name},

+

เราได้รับข้อความของคุณแล้ว และจะตอบกลับภายใน 24 ชั่วโมงทำการ

+
+ ข้อความของคุณ:
+ ${message.substring(0, 200)}${message.length > 200 ? "..." : ""} +
+

หากมีเรื่องด่วน สามารถติดต่อเราได้โดยตรงที่:

+

+ 📞 080-995-5945
+ 📧 contact@moreminimore.com +

+

ขอบคุณครับ/ค่ะ
MoreminiMore Team

+
+ +
+ +`, + }); + } + + return new Response( + JSON.stringify({ + success: true, + message: smtpHost ? "ส่งข้อความเรียบร้อยแล้ว เราจะติดต่อกลับภายใน 24 ชั่วโมง" : "บันทึกข้อความเรียบร้อยแล้ว" + }), + { status: 200, headers: { "Content-Type": "application/json" } } + ); + } catch (error) { + console.error("[Contact API] Error:", error); + return new Response( + JSON.stringify({ success: false, error: "เกิดข้อผิดพลาด กรุณาลองใหม่อีกครั้ง" }), + { status: 500, headers: { "Content-Type": "application/json" } } + ); + } +}; diff --git a/templates/marketing/src/pages/contact.astro b/templates/marketing/src/pages/contact.astro index d5263c2..71a9ae5 100644 --- a/templates/marketing/src/pages/contact.astro +++ b/templates/marketing/src/pages/contact.astro @@ -1,250 +1,161 @@ --- -import { getEmDashEntry } from "emdash"; import Base from "../layouts/Base.astro"; -import MarketingBlocks from "../components/MarketingBlocks.astro"; - -const { entry: page, cacheHint } = await getEmDashEntry("pages", "contact"); - -try { - Astro.cache.set(cacheHint); -} catch {} - -// Handle form submission -// NOTE: This is demo code. For production, add: -// - CSRF token validation -// - Rate limiting (e.g., via Cloudflare or middleware) -// - Actual email sending or webhook integration -let formStatus: "idle" | "success" | "error" = "idle"; -let formMessage = ""; - -if (Astro.request.method === "POST") { - try { - const formData = await Astro.request.formData(); - const name = formData.get("name")?.toString() || ""; - const email = formData.get("email")?.toString() || ""; - const company = formData.get("company")?.toString() || ""; - const message = formData.get("message")?.toString() || ""; - - if (!name || !email || !message) { - formStatus = "error"; - formMessage = "Please fill in all required fields."; - } else if (!email.includes("@")) { - formStatus = "error"; - formMessage = "Please enter a valid email address."; - } else { - // TODO: Replace with actual email/webhook integration - console.log("Contact form submission:", { - name, - email, - company, - message, - }); - formStatus = "success"; - formMessage = - "Thanks for reaching out! We'll get back to you within 24 hours."; - } - } catch { - formStatus = "error"; - formMessage = "Something went wrong. Please try again."; - } -} - -const pageContent = page?.data.content; --- - {pageContent && } - -
+
-
-
-

Talk to our team

-

Fill out the form and we'll be in touch within 24 hours.

+

ติดต่อเรา

+

พร้อมให้คำปรึกษาฟรี! ติดต่อมาได้เลย

+
+
-
-
-
- -
-
-

Email

- hello@acme.example -
+
+
+
+

ช่องทางการติดต่อ

+
+
+ +
+

โทรศัพท์

+

080-995-5945

-
-
- -
-
-

Support

- support@acme.example -
+
+
+ +
+

อีเมล

+

contact@moreminimore.com

-
-
- -
-
-

Sales

- sales@acme.example -
+
+
+ +
+

ที่อยู่

+

53 หมู่ 1 ต.บ้านแพ้ว
อ.บ้านแพ้ว สมุทรสาคร 74120

+
+
+
+ +
+

เวลาทำการ

+

จ-ศ: 9:00-18:00
ส: 10:00-16:00

- -
- { - formStatus === "success" ? ( -
-
-

Message Sent!

-

{formMessage}

- - Send another message - -
- ) : ( -
- {formStatus === "error" && ( -
-

{formMessage}

-
- )} - -
-
- - -
-
- - -
-
- -
- - -
- -
- - +
+ + +
+
+ + diff --git a/templates/marketing/src/pages/services/web-development.astro b/templates/marketing/src/pages/services/web-development.astro new file mode 100644 index 0000000..c23b2ac --- /dev/null +++ b/templates/marketing/src/pages/services/web-development.astro @@ -0,0 +1,223 @@ +--- +import { getEmDashEntry } from "emdash"; +import Base from "../../layouts/Base.astro"; +import MarketingBlocks from "../../components/MarketingBlocks.astro"; + +const { entry, cacheHint } = await getEmDashEntry("pages", "services/web-development"); + +try { + Astro.cache.set(cacheHint); +} catch {} + +const pageContent = entry?.data.content; +--- + + + {pageContent ? ( + + ) : ( +
+
+ Web Development +

Web Development

+

เว็บไซต์ที่ลูกค้าปรับเองได้ด้วย AI Editor พร้อม SEO และ Dark Mode

+ ปรึกษาฟรี +
+
+ )} + +
+
+

เทคโนโลยีที่เราใช้

+
+
+

Astro

+

เว็บไซต์เร็ว ปลอดภัย SEO ดี เริ่มต้น 5,000 บาท

+
+
+

WordPress

+

CMS ยอดนิยม ปรับแต่งง่าย เริ่มต้น 10,000 บาท

+
+
+

AI Editor

+

ลูกค้าปรับเนื้อหาได้เองง่ายๆ ด้วย AI

+
+
+
+
+ +
+
+
+

ราคา Web Development

+

เลือกแพ็กเกจที่เหมาะกับธุรกิจคุณ

+
+
+
+

Astro Starter

+
+ 5,000 + บาท +
+

เหมาะสำหรับเว็บไซต์พื้นฐาน 5 หน้า

+
    +
  • 5 sections
  • +
  • Mobile responsive
  • +
  • AI content editor
  • +
  • SEO พื้นฐาน
  • +
  • 1 เดือน support
  • +
  • Hosting หรือ deploy ให้
  • +
+ ติดต่อสอบถาม +
+
+
ยอดนิยม
+

WordPress Starter

+
+ 10,000 + บาท +
+

เหมาะสำหรับเว็บไซต์ที่ต้องการ CMS ยืดหยุ่น

+
    +
  • 5 sections
  • +
  • Mobile responsive
  • +
  • AI content editor
  • +
  • SEO ขั้นสูง
  • +
  • 1 เดือน support
  • +
  • Hosting หรือ deploy ให้
  • +
+ ติดต่อสอบถาม +
+
+

* ราคาไม่รวมโดเมนและโฮสติ้ง ราคาขึ้นอยู่กับความซับซ้อนของงาน

+
+
+ +
+
+

พร้อมสร้างเว็บไซต์แล้วหรือยัง?

+

ติดต่อเราวันนี้ พร้อมให้คำปรึกษาฟรี

+ ปรึกษาฟรี +
+
+ + +