feat: full site build — Project/Melody schema (Option A), admin CRUD, public sections, uploads, email+SMTP, internal analytics, legal pages, docs

This commit is contained in:
2026-08-05 20:53:40 +02:00
parent d87f3033c6
commit c26f41511f
122 changed files with 15068 additions and 41 deletions
+102
View File
@@ -0,0 +1,102 @@
import type { Locale } from "@/lib/i18n";
import { legalConfig, siteConfig } from "@/lib/site";
export type LegalSection = { heading: string; paragraphs?: string[]; list?: string[] };
export type LegalDocument = { title: string; intro: string; updatedLabel: string; sections: LegalSection[] };
export type LegalPage = "privacy" | "terms" | "impressum";
function configured(value: string, fallback: string) {
return value || fallback;
}
export function getLegalDocument(locale: Locale, page: LegalPage): LegalDocument {
const isArabic = locale === "ar";
const email = configured(siteConfig.email, isArabic ? "أضف البريد في ملف البيئة" : "Configure the contact email in the environment");
const address = [legalConfig.address, [legalConfig.postalCode, legalConfig.city].filter(Boolean).join(" "), legalConfig.country].filter(Boolean);
const addressText = configured(address.join(", "), isArabic ? "أضف العنوان القانوني في ملف البيئة" : "Configure the legal address in the environment");
const owner = legalConfig.name;
const lastUpdated = "2026-08-05";
const documents: Record<Locale, Record<LegalPage, LegalDocument>> = {
ar: {
privacy: {
title: "سياسة الخصوصية",
intro: "توضح هذه الصفحة كيف يتعامل موقع ضياء مع البيانات التي تُرسل من خلال نموذج التواصل والبيانات التقنية اللازمة لتشغيل الموقع.",
updatedLabel: `آخر تحديث: ${lastUpdated}`,
sections: [
{ heading: "المسؤول عن المعالجة", paragraphs: [`${owner}، ${addressText}`, `البريد الإلكتروني: ${email}`] },
{ heading: "البيانات التي نجمعها", paragraphs: ["عند استخدام نموذج التواصل قد نعالج الاسم والبريد الإلكتروني ومحتوى الرسالة. قد يعالج الخادم أيضاً بيانات تقنية ضرورية لتقديم الموقع وحمايته من إساءة الاستخدام."] },
{ heading: "الغرض والأساس القانوني", paragraphs: ["نستخدم بيانات نموذج التواصل للرد على الاستفسارات وتنفيذ الخطوات المطلوبة قبل التعاقد عند الاقتضاء. يكون الأساس القانوني عادةً تنفيذ طلبك أو مصلحتنا المشروعة في إدارة التواصل المهني، بحسب طبيعة الرسالة."] },
{ heading: "الإرسال والتخزين", paragraphs: ["تُحفظ رسائل التواصل في قاعدة بيانات الموقع، ويُرسل إشعار بها عبر مزود SMTP مضبوط في إعدادات الخادم. لا نبيع البيانات ولا نستخدمها للإعلانات، ونحتفظ بها فقط للمدة اللازمة لمعالجة الطلب والالتزامات القانونية."] },
{ heading: "الحماية من الرسائل المزعجة", paragraphs: ["يستخدم النموذج حقلاً مخفياً وتحديداً مؤقتاً لمعدل الطلبات. لا يُستخدم عنوان المصدر المحسوب للحماية كجزء من ملف تسويقي."] },
{ heading: "حقوقك", paragraphs: ["بحسب القوانين المعمول بها، قد يحق لك طلب الوصول إلى بياناتك أو تصحيحها أو حذفها أو تقييد معالجتها أو الاعتراض عليها، كما يمكنك تقديم شكوى إلى جهة حماية البيانات المختصة. تواصل معنا عبر البريد أعلاه لممارسة حق من هذه الحقوق."] },
{ heading: "التحديثات", paragraphs: ["قد نحدّث هذه السياسة عند تغيير الموقع أو طريقة معالجة البيانات. سيظهر تاريخ آخر تحديث في أعلى الصفحة."] },
],
},
terms: {
title: "شروط الاستخدام",
intro: "تحدد هذه الشروط الإطار العام لاستخدام موقع ضياء ومحتواه العام.",
updatedLabel: `آخر تحديث: ${lastUpdated}`,
sections: [
{ heading: "نطاق الاستخدام", paragraphs: ["يمكنك تصفح الموقع واستخدام محتواه لأغراض شخصية أو مهنية مشروعة. لا يجوز استخدام الموقع بطريقة تضر به أو تتجاوز الضوابط التقنية أو تنتهك حقوق الآخرين."] },
{ heading: "المحتوى وحقوق الملكية", paragraphs: ["ما لم يُذكر خلاف ذلك، تعود حقوق النصوص والصور والتصاميم والمشاريع المعروضة إلى مالكها أو أصحاب الحقوق المعنيين. لا يجوز نسخ المحتوى أو إعادة نشره أو استخدامه تجارياً دون إذن مناسب."] },
{ heading: "التوفر والروابط الخارجية", paragraphs: ["نسعى إلى إبقاء الموقع متاحاً ودقيقاً، لكن لا نضمن التوفر الدائم أو خلو المحتوى من الأخطاء. قد يحتوي الموقع على روابط لخدمات خارجية؛ تقع مسؤولية استخدام تلك الخدمات على مشغليها."] },
{ heading: "التواصل", paragraphs: [`للاستفسارات حول هذه الشروط تواصل مع ${owner} عبر ${email}.`] },
{ heading: "التعديلات", paragraphs: ["يجوز تحديث هذه الشروط عند تطور الموقع أو الخدمات. تسري النسخة المنشورة على الاستخدام اللاحق للموقع."] },
],
},
impressum: {
title: "Impressum · بيانات المزوّد",
intro: "بيانات المزوّد المطلوبة للموقع المهني. يجب إكمال الحقول من ملف البيئة قبل النشر العام.",
updatedLabel: `آخر تحديث: ${lastUpdated}`,
sections: [
{ heading: "المزوّد", paragraphs: [owner, addressText] },
{ heading: "التواصل المباشر", paragraphs: [`البريد الإلكتروني: ${email}`] },
{ heading: "بيانات إضافية", paragraphs: [legalConfig.vatId ? `رقم ضريبة القيمة المضافة: ${legalConfig.vatId}` : "لم يتم ضبط رقم ضريبة القيمة المضافة في ملف البيئة."] },
{ heading: "تنبيه الإكمال", paragraphs: ["تحقق من الاسم والعنوان والبيانات المهنية الفعلية مع مستشارك القانوني قبل إطلاق الموقع. هذه الصفحة قالب تقني وليست استشارة قانونية."] },
],
},
},
en: {
privacy: {
title: "Privacy policy",
intro: "This page explains how Diyaa handles data submitted through the contact form and the technical data needed to operate the website.",
updatedLabel: `Last updated: ${lastUpdated}`,
sections: [
{ heading: "Controller", paragraphs: [`${owner}, ${addressText}`, `Email: ${email}`] },
{ heading: "Data we collect", paragraphs: ["When you use the contact form, we may process your name, email address, and message. The server may also process technical data necessary to deliver the site and prevent abuse."] },
{ heading: "Purpose and legal basis", paragraphs: ["We use contact-form data to respond to inquiries and, where applicable, take steps at your request before entering into a contract. The legal basis depends on the nature of the inquiry and may be contract-related processing or our legitimate interest in professional communication."] },
{ heading: "Delivery and storage", paragraphs: ["Contact messages are stored in the website database and an email notification is sent through the SMTP provider configured on the server. We do not sell the data or use it for advertising, and retain it only as long as needed to handle the inquiry and meet legal obligations."] },
{ heading: "Spam protection", paragraphs: ["The form uses a hidden honeypot field and temporary request throttling. The source address used for this protection is not used as a marketing profile."] },
{ heading: "Your rights", paragraphs: ["Depending on applicable law, you may have rights to access, correct, delete, restrict, or object to processing of your data, and to complain to a competent data-protection authority. Contact us at the email above to exercise a right."] },
{ heading: "Updates", paragraphs: ["We may update this policy when the website or its processing practices change. The latest update date is shown above."] },
],
},
terms: {
title: "Terms of use",
intro: "These terms provide the general framework for using the Diyaa website and its public content.",
updatedLabel: `Last updated: ${lastUpdated}`,
sections: [
{ heading: "Permitted use", paragraphs: ["You may browse and use the website for lawful personal or professional purposes. You must not use it in a way that harms the site, bypasses technical safeguards, or infringes the rights of others."] },
{ heading: "Content and intellectual property", paragraphs: ["Unless stated otherwise, texts, images, designs, and showcased projects belong to their owner or the respective rights holders. Do not copy, republish, or commercially use content without appropriate permission."] },
{ heading: "Availability and external links", paragraphs: ["We aim to keep the website available and accurate, but do not guarantee uninterrupted availability or error-free content. External links lead to services operated by third parties, whose operators are responsible for their own services."] },
{ heading: "Contact", paragraphs: [`For questions about these terms, contact ${owner} at ${email}.`] },
{ heading: "Changes", paragraphs: ["These terms may be updated as the website or services evolve. The published version applies to future use of the website."] },
],
},
impressum: {
title: "Legal notice",
intro: "Provider information for this professional website. Complete the environment fields before public launch.",
updatedLabel: `Last updated: ${lastUpdated}`,
sections: [
{ heading: "Provider", paragraphs: [owner, addressText] },
{ heading: "Direct contact", paragraphs: [`Email: ${email}`] },
{ heading: "Additional information", paragraphs: [legalConfig.vatId ? `VAT ID: ${legalConfig.vatId}` : "No VAT ID has been configured in the environment."] },
{ heading: "Completion notice", paragraphs: ["Verify the actual name, address, and professional details with your legal adviser before launching the website. This page is a technical template, not legal advice."] },
],
},
},
};
return documents[locale][page];
}