+
-
+
@@ -46,4 +49,10 @@ const { data: site } = await useAsyncData("public-site", () => fetchPublicSite()
});
const homePage = computed(() => site.value?.pages?.find((p: any) => p.key === "home"));
applyPageSeo(homePage.value?.seo);
+
+const loaderTitle = useState("intro-loader-title", () => "هوشافزار منتک");
+watchEffect(() => {
+ const hero = site.value?.sections?.hero as { loaderTitle?: string } | undefined;
+ if (hero?.loaderTitle) loaderTitle.value = hero.loaderTitle;
+});
diff --git a/scripts/local-mock-api.mjs b/scripts/local-mock-api.mjs
new file mode 100644
index 0000000..bc5a659
--- /dev/null
+++ b/scripts/local-mock-api.mjs
@@ -0,0 +1,182 @@
+/**
+ * Lightweight local mock API for UI preview when Postgres isn't configured.
+ * Serves the same shape as Nest public endpoints from seed defaults.
+ */
+import http from "node:http";
+
+const sections = {
+ hero: {
+ eyebrow: "گروه توسعه نرمافزار",
+ location: "[ تأسیس ۱۴۰۰ — تهران / دورکاری ]",
+ loaderTitle: "هوشافزار منتک",
+ lines: [
+ "در هوشافزار منتک",
+ "بهترین نرمافزارها و خدمات",
+ "متناسب با کسبوکار شما پیشنهاد میشود",
+ ],
+ highlightWord: "هوشافزار منتک",
+ highlightWords: ["هوشافزار منتک"],
+ body: "منتک یک تیم مهندسی ارشد است که پلتفرمهای وب، اپلیکیشن موبایل و زیرساخت ابری را برای کسبوکارهایی میسازد که نمیخواهند معمولی باشند.",
+ cta: "مشاهده نمونهکارها",
+ badge: "مهندسی منتک • از ۱۴۰۰ •",
+ coords: "تهران، ایران",
+ projectsLabel: "بیش از ۱۲۰ پروژه تحویلشده",
+ },
+ marquee: {
+ items: [
+ "آبشده همکار",
+ "آبشده خانگی",
+ "فروشگاه آنلاین",
+ "سامانه بد و بس",
+ "سامانه فوری سند",
+ "مدیریت ارتباط با مشتری CRM",
+ "هوش مصنوعی",
+ ],
+ },
+ manifesto: {
+ tag: "ما که هستیم",
+ words: [
+ { text: "ما" },
+ { text: "نرمافزاری" },
+ { text: "میسازیم", volt: true },
+ { text: "که" },
+ { text: "تفاوت" },
+ { text: "ایجاد" },
+ { text: "کند." },
+ { text: "منتک", volt: true },
+ ],
+ body: "استراتژی، طراحی و مهندسی زیر یک سقف — با دقت وسواسگونه نسبت به کیفیت و عملکرد.",
+ },
+ services: {
+ tag: "چه میکنیم",
+ items: [
+ { n: "۰۱", title: "استراتژی محصول", desc: "ایدههای مبهم را به نقشه راه معتبر تبدیل میکنیم.", tags: ["کشف محصول", "پژوهش کاربر", "نقشه راه", "MVP"] },
+ { n: "۰۲", title: "مهندسی وب", desc: "پلتفرمهای وب سریع و مقیاسپذیر.", tags: ["Nuxt", "NestJS", "Node.js", "React"] },
+ { n: "۰۳", title: "اپلیکیشن موبایل", desc: "تجربهٔ بومیگونه روی iOS و Android.", tags: ["React Native", "Flutter"] },
+ { n: "۰۴", title: "ابرو DevOps", desc: "استقرار خودکار، امنیت و مانیتورینگ.", tags: ["AWS / GCP", "کوبرنتیز", "CI/CD"] },
+ { n: "۰۵", title: "هوش مصنوعی و داده", desc: "هوش مصنوعی کاربردی و خطوط لوله داده.", tags: ["LLM", "اتوماسیون"] },
+ ],
+ },
+ work: {
+ tag: "نمونه کارها",
+ items: [
+ { n: "۰۱", title: "پالسبورد", cat: "پلتفرم تحلیلی فینتک", year: "۱۴۰۳" },
+ { n: "۰۲", title: "ایرولوپ", cat: "نرمافزار لجستیک", year: "۱۴۰۳" },
+ { n: "۰۳", title: "مدسینک", cat: "پلتفرم هلثتک", year: "۱۴۰۲" },
+ { n: "۰۴", title: "نوواپی", cat: "زیرساخت پرداخت", year: "۱۴۰۲" },
+ ],
+ },
+ process: {
+ tag: "چگونه کار میکنیم",
+ steps: [
+ { n: "۰۱", title: "کشف", desc: "کارگاه، پژوهش و همراستایی روی نتایج." },
+ { n: "۰۲", title: "طراحی", desc: "سیستمها، جریانها و رابطهای ساده." },
+ { n: "۰۳", title: "توسعه", desc: "مهندسان ارشد و نرمافزار آمادهٔ تولید." },
+ { n: "۰۴", title: "استقرار و مقیاس", desc: "CI/CD، مانیتورینگ و رشد پایدار." },
+ ],
+ },
+ stats: {
+ items: [
+ { value: 120, suffix: "+", label: "پروژه تحویلشده" },
+ { value: 40, suffix: "+", label: "مشتری" },
+ { value: 15, suffix: "", label: "مهندس و طراح" },
+ { value: 98, suffix: "%", label: "ماندگاری مشتری" },
+ ],
+ },
+ team: {
+ tag: "تیم",
+ headline: "با جمع ما آشنا شوید",
+ body: "تیمی جمعوجور از متخصصان محصول، طراحی و مهندسی.",
+ members: [
+ { name: "علی رضایی", role: "مدیرعامل و همبنیانگذار" },
+ { name: "سارا محمدی", role: "مدیر فنی و همبنیانگذار" },
+ { name: "مریم حسینی", role: "سرپرست طراحی" },
+ { name: "رضا کریمی", role: "مهندس ارشد" },
+ ],
+ },
+ footer: {
+ tag: "تماس",
+ marquee: ["پروژهای در ذهن دارید؟", "سلام کنید", "با هم کار کنیم"],
+ cta: "شروع همکاری",
+ },
+};
+
+const site = {
+ settings: {
+ brandName: "منتک",
+ tagline: "گروه توسعه نرمافزار",
+ email: "hello@montech.ir",
+ phone: "+98 21 0000 0000",
+ address: "تهران، ایران",
+ timezone: "Asia/Tehran",
+ logoUrl: null,
+ socials: [
+ { label: "لینکدین", url: "https://linkedin.com" },
+ { label: "گیتهاب", url: "https://github.com" },
+ ],
+ },
+ sections,
+ pages: [
+ {
+ key: "home",
+ title: "خانه",
+ seo: {
+ title: "منتک — گروه توسعه نرمافزار",
+ description: "منتک پلتفرمهای وب، اپلیکیشن موبایل و زیرساخت ابری میسازد.",
+ canonical: "http://localhost:3000/",
+ },
+ },
+ ],
+};
+
+const blog = [
+ {
+ id: "1",
+ slug: "welcome-to-montech",
+ title: "به منتک خوش آمدید",
+ excerpt: "ما نرمافزاری میسازیم که واقعاً کار میکند.",
+ publishedAt: new Date().toISOString(),
+ },
+];
+
+const port = Number(process.env.PORT || 3050);
+
+const server = http.createServer((req, res) => {
+ res.setHeader("Access-Control-Allow-Origin", "*");
+ res.setHeader("Access-Control-Allow-Methods", "GET,OPTIONS");
+ res.setHeader("Access-Control-Allow-Headers", "Content-Type");
+ if (req.method === "OPTIONS") {
+ res.writeHead(204);
+ res.end();
+ return;
+ }
+
+ const url = req.url || "/";
+ const json = (data, code = 200) => {
+ res.writeHead(code, { "Content-Type": "application/json; charset=utf-8" });
+ res.end(JSON.stringify(data));
+ };
+
+ if (url === "/api/health") return json({ ok: true, mock: true });
+ if (url === "/api/public/site") return json(site);
+ if (url === "/api/public/blog") return json(blog);
+ if (url.startsWith("/api/public/blog/")) {
+ const slug = decodeURIComponent(url.split("/").pop() || "");
+ const post = blog.find((p) => p.slug === slug);
+ return post
+ ? json({ ...post, content: "محتوای نمونه برای پیشنمایش لوکال." })
+ : json({ message: "Not found" }, 404);
+ }
+ if (url === "/api/public/gallery") return json([]);
+ if (url.startsWith("/api/public/pages/")) {
+ const key = decodeURIComponent(url.split("/").pop() || "");
+ const page = site.pages.find((p) => p.key === key);
+ return page ? json(page) : json({ message: "Not found" }, 404);
+ }
+
+ json({ message: `Mock API — no route for ${url}` }, 404);
+});
+
+server.listen(port, "127.0.0.1", () => {
+ console.log(`[mock-api] http://127.0.0.1:${port}`);
+});