Files
meezi/web/website/src/app/[locale]/terms/page.tsx
T
soroush.asadi 166f2b2586
CI/CD / CI · API (dotnet build + test) (push) Successful in 1m4s
CI/CD / CI · Admin API (dotnet build) (push) Successful in 30s
CI/CD / CI · Dashboard (tsc) (push) Successful in 1m9s
CI/CD / CI · Admin Web (tsc) (push) Successful in 38s
CI/CD / CI · Website (tsc) (push) Successful in 46s
CI/CD / CI · Koja (tsc) (push) Successful in 52s
CI/CD / Deploy · all services (push) Successful in 2m1s
fix(seo): self-canonical + unique description on 6 pages that deduped to home
contact / careers / status / privacy / terms / docs set no alternates, so they
inherited the layout's canonical (= the locale homepage) — Google treats them as
duplicates of the home page and drops them. Each now sets a self-referencing
canonical + full fa/en/x-default hreflang (new shared lib/seo.ts pageAlternates)
and a unique meta description (added *Desc keys, fa/en) + per-page OpenGraph.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24 21:32:08 +03:30

223 lines
10 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import type { Metadata } from "next";
import { getTranslations } from "next-intl/server";
import { SITE_URL, pageAlternates } from "@/lib/seo";
import { Navbar } from "@/components/layout/navbar";
import { Footer } from "@/components/layout/footer";
import { FileText } from "lucide-react";
export async function generateMetadata({
params,
}: {
params: Promise<{ locale: string }>;
}): Promise<Metadata> {
const { locale } = await params;
const t = await getTranslations({ locale, namespace: "meta" });
return {
title: t("termsTitle"),
description: t("termsDesc"),
alternates: pageAlternates(locale, "/terms"),
openGraph: { title: t("termsTitle"), description: t("termsDesc"), url: `${SITE_URL}/${locale}/terms` },
};
}
const fa = {
badge: "حقوقی",
title: "شرایط استفاده از خدمات",
updated: "آخرین به‌روزرسانی: خرداد ۱۴۰۴",
sections: [
{
h: "۱. پذیرش شرایط",
body: `با ثبت‌نام در میزی و استفاده از خدمات آن، شما این شرایط را می‌پذیرید. اگر با هر بخشی از این شرایط موافق نیستید، از ثبت‌نام و استفاده از سرویس خودداری کنید.`,
},
{
h: "۲. شرح خدمات",
body: `میزی یک پلتفرم نرم‌افزاری (SaaS) برای مدیریت کافه‌ها و رستوران‌هاست که شامل موارد زیر می‌شود:
• منوی دیجیتال QR
• سیستم فروش (POS) و مدیریت سفارش
• آشپزخانه دیجیتال (KDS)
• مدیریت موجودی و انبار
• گزارش‌های فروش و تحلیل داده
• مدیریت کارکنان و شیفت‌بندی
• مدیریت چند شعبه
میزی حق دارد هر زمان با اطلاع‌رسانی قبلی، ویژگی‌ها را تغییر دهد یا به‌روزرسانی کند.`,
},
{
h: "۳. حساب کاربری",
body: `• مسئولیت حفاظت از رمز عبور و کد OTP با شماست.
• اطلاعات حساب باید دقیق و به‌روز باشد.
• استفاده از حساب دیگران بدون مجوز ممنوع است.
• در صورت مشاهده دسترسی غیرمجاز، فوراً با پشتیبانی تماس بگیرید.
• هر حساب کاربری مربوط به یک کسب‌وکار مشخص است.`,
},
{
h: "۴. هزینه‌ها و پرداخت",
body: `• هزینه اشتراک بر اساس پلن انتخابی در ابتدای هر دوره پرداخت می‌شود.
• تمام قیمت‌ها به تومان و شامل مالیات ارزش افزوده است.
• در صورت عدم پرداخت، حساب تا ۷ روز در حالت محدود قرار می‌گیرد.
• استرداد وجه برای ماه جاری امکان‌پذیر نیست؛ درخواست لغو از ماه آینده اعمال می‌شود.
• پلن رایگان می‌تواند در هر زمان بدون هزینه استفاده شود.`,
},
{
h: "۵. استفاده مجاز",
body: `کاربران موافقت می‌کنند که:
• از سرویس فقط برای اهداف قانونی استفاده کنند.
• داده‌های مشتریان نهایی را با احترام و طبق قوانین ایران نگه دارند.
• از هرگونه دسترسی غیرمجاز، ریورس‌انجینیرینگ یا کپی‌برداری از کد خودداری کنند.
• محتوای توهین‌آمیز، گمراه‌کننده یا غیرقانونی در سیستم وارد نکنند.`,
},
{
h: "۶. مالکیت معنوی",
body: `تمام محتوا، نرم‌افزار، برند و طراحی میزی متعلق به شرکت است. داده‌های کسب‌وکار شما (منو، مشتریان، سفارش‌ها) متعلق به شماست. میزی مجاز نیست داده‌های شما را بدون اجازه برای اهداف تجاری استفاده کند.`,
},
{
h: "۷. تعلیق و فسخ",
body: `میزی حق دارد در موارد زیر حساب را تعلیق یا فسخ کند:
• نقض این شرایط
• عدم پرداخت پس از ۳۰ روز تأخیر
• فعالیت‌های مشکوک یا تقلبی
در صورت فسخ توسط کاربر، تا ۳۰ روز امکان دریافت خروجی داده‌ها وجود دارد.`,
},
{
h: "۸. محدودیت مسئولیت",
body: `میزی در قبال موارد زیر مسئولیتی ندارد:
• خسارات ناشی از قطعی اینترنت یا برق کاربر
• خطاهای انسانی در ورود اطلاعات
• خسارات غیرمستقیم یا از دست رفتن سود
حداکثر مسئولیت میزی معادل یک ماه هزینه اشتراک است.`,
},
{
h: "۹. تغییرات",
body: `میزی می‌تواند این شرایط را با اطلاع‌رسانی ۱۴ روزه تغییر دهد. ادامه استفاده از سرویس به منزله پذیرش شرایط جدید است.`,
},
{
h: "۱۰. قانون حاکم",
body: `این قرارداد تابع قوانین جمهوری اسلامی ایران است. هرگونه اختلاف در دادگاه‌های تهران رسیدگی می‌شود.`,
},
],
};
const en = {
badge: "Legal",
title: "Terms of Service",
updated: "Last updated: June 2026",
sections: [
{
h: "1. Acceptance of Terms",
body: `By registering for and using Meezi, you accept these terms. If you disagree with any part of these terms, do not register or use the service.`,
},
{
h: "2. Service Description",
body: `Meezi is a software-as-a-service (SaaS) platform for managing cafes and restaurants, including:
• QR digital menu
• Point of Sale (POS) and order management
• Kitchen Display System (KDS)
• Inventory and stock management
• Sales reports and data analytics
• Staff management and shift scheduling
• Multi-branch management
Meezi reserves the right to modify or update features at any time with prior notice.`,
},
{
h: "3. User Account",
body: `• You are responsible for protecting your password and OTP codes.
• Account information must be accurate and up to date.
• Using another person's account without authorization is prohibited.
• Report any unauthorized access to support immediately.
• Each account is associated with a specific business.`,
},
{
h: "4. Fees and Payment",
body: `• Subscription fees are charged at the start of each billing period based on the selected plan.
• All prices are in Tomans and include VAT.
• Non-payment results in a restricted account for up to 7 days.
• Refunds are not available for the current month; cancellations take effect from the next billing period.
• The free plan can be used at any time at no cost.`,
},
{
h: "5. Acceptable Use",
body: `Users agree to:
• Use the service only for lawful purposes.
• Handle end-customer data respectfully and in accordance with Iranian law.
• Refrain from unauthorized access, reverse engineering, or copying the code.
• Not enter offensive, misleading, or illegal content into the system.`,
},
{
h: "6. Intellectual Property",
body: `All content, software, brand, and design of Meezi belongs to the company. Your business data (menu, customers, orders) belongs to you. Meezi is not permitted to use your data for commercial purposes without permission.`,
},
{
h: "7. Suspension and Termination",
body: `Meezi reserves the right to suspend or terminate accounts in cases of:
• Violation of these terms
• Non-payment after 30 days
• Suspicious or fraudulent activity
Upon user-initiated cancellation, data export is available for 30 days.`,
},
{
h: "8. Limitation of Liability",
body: `Meezi is not liable for:
• Damages from the user's internet or power outage
• Human errors in data entry
• Indirect damages or loss of profit
Meezi's maximum liability is equivalent to one month's subscription fee.`,
},
{
h: "9. Changes",
body: `Meezi may change these terms with 14 days' notice. Continued use of the service constitutes acceptance of the new terms.`,
},
{
h: "10. Governing Law",
body: `This agreement is governed by the laws of the Islamic Republic of Iran. Any disputes will be resolved in Tehran courts.`,
},
],
};
export default async function TermsPage({
params,
}: {
params: Promise<{ locale: string }>;
}) {
const { locale } = await params;
const c = locale === "fa" ? fa : en;
return (
<>
<Navbar />
<main className="pt-16">
{/* Hero */}
<div className="bg-gradient-to-br from-brand-900 to-brand-700 pb-16 pt-16 text-center">
<div className="mx-auto flex h-14 w-14 items-center justify-center rounded-2xl bg-white/10">
<FileText className="h-7 w-7 text-white" />
</div>
<span className="mt-4 inline-flex items-center gap-1.5 rounded-full border border-white/20 bg-white/10 px-3 py-1 text-xs font-semibold text-white/80">
{c.badge}
</span>
<h1 className="mt-3 text-3xl font-extrabold text-white sm:text-4xl">{c.title}</h1>
<p className="mt-2 text-sm text-white/50">{c.updated}</p>
</div>
{/* Content */}
<div className="mx-auto max-w-3xl px-4 py-16 sm:px-6 lg:px-8">
<div className="space-y-10">
{c.sections.map((sec) => (
<div key={sec.h}>
<h2 className="mb-3 text-lg font-bold text-gray-900">{sec.h}</h2>
<div className="whitespace-pre-line text-sm leading-relaxed text-gray-600">
{sec.body}
</div>
</div>
))}
</div>
</div>
</main>
<Footer />
</>
);
}