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:
meshkee.ai10
2026-09-04 11:51:32 +03:30
co-authored by Claude Sonnet 5
commit 028a91944c
104 changed files with 4715 additions and 0 deletions
+75
View File
@@ -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,
});
}