Dejband.com clone — Next.js, RTL Persian
- Homepage faithfully matching dejband.com (hero, services, consulting,
stats, about block, timeline, portfolio, articles) + About/Contact/
Portfolios/Articles pages under source URLs
- Meshkee API integration: live blog content, favicon, user menu,
sitemap/robots proxy, canonical /blog/{id}/{slug}
- SEO pass: one H1 per page, unique metadata + canonicals, alt text
- Contact form wired to /api/contact with toast + reset
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
import { DOMAIN, API_BASE } from "@/lib/api";
|
||||
|
||||
// Contact form endpoint.
|
||||
// Validates the submission and — when an SMS key is configured — notifies the
|
||||
// business through the Meshkee SMS gateway. Without a key it still accepts the
|
||||
// message so the storefront keeps working; wire delivery by setting:
|
||||
// MESHKEE_SMS_API_KEY server-to-server key for /public/sms/send
|
||||
// MESHKEE_CONTACT_NOTIFY_TO phone number that should receive the alert
|
||||
|
||||
export const runtime = "nodejs";
|
||||
|
||||
const faDigits = (s) => String(s).replace(/[۰-۹]/g, (d) => "۰۱۲۳۴۵۶۷۸۹".indexOf(d));
|
||||
|
||||
function validate(body) {
|
||||
const name = String(body?.name || "").trim();
|
||||
const phone = faDigits(body?.phone || "").trim();
|
||||
const email = String(body?.email || "").trim();
|
||||
const message = String(body?.message || "").trim();
|
||||
|
||||
const errors = {};
|
||||
if (name.length < 2) errors.name = "نام را وارد کنید";
|
||||
if (!/^0?\d{10,11}$/.test(phone.replace(/[\s-]/g, "")))
|
||||
errors.phone = "شماره تماس معتبر نیست";
|
||||
if (email && !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email))
|
||||
errors.email = "ایمیل معتبر نیست";
|
||||
if (message.length < 5) errors.message = "متن پیام را وارد کنید";
|
||||
|
||||
return { data: { name, phone, email, message }, errors };
|
||||
}
|
||||
|
||||
async function notifyBusiness({ name, phone, email, message }) {
|
||||
const key = process.env.MESHKEE_SMS_API_KEY;
|
||||
const to = process.env.MESHKEE_CONTACT_NOTIFY_TO;
|
||||
if (!key || !to) return { delivered: false, reason: "not-configured" };
|
||||
|
||||
const text = `پیام جدید از فرم تماس دژبند\nنام: ${name}\nتماس: ${phone}${
|
||||
email ? `\nایمیل: ${email}` : ""
|
||||
}\nپیام: ${message}`.slice(0, 600);
|
||||
|
||||
try {
|
||||
const res = await fetch(`${API_BASE}/public/sms/send`, {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json", "X-Api-Key": key },
|
||||
body: JSON.stringify({ domain: DOMAIN, to, message: text }),
|
||||
});
|
||||
return { delivered: res.ok, reason: res.ok ? "sent" : `sms-${res.status}` };
|
||||
} catch {
|
||||
return { delivered: false, reason: "sms-error" };
|
||||
}
|
||||
}
|
||||
|
||||
export async function POST(request) {
|
||||
let body;
|
||||
try {
|
||||
body = await request.json();
|
||||
} catch {
|
||||
return Response.json({ ok: false, message: "درخواست نامعتبر است" }, { status: 400 });
|
||||
}
|
||||
|
||||
const { data, errors } = validate(body);
|
||||
if (Object.keys(errors).length) {
|
||||
return Response.json(
|
||||
{ ok: false, message: "لطفاً فیلدها را بررسی کنید", errors },
|
||||
{ status: 422 }
|
||||
);
|
||||
}
|
||||
|
||||
const notify = await notifyBusiness(data);
|
||||
|
||||
return Response.json({
|
||||
ok: true,
|
||||
message: "پیام شما با موفقیت ثبت شد. بهزودی همکاران ما با شما تماس میگیرند.",
|
||||
delivered: notify.delivered,
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user