From f892fc4a4d88d288811174eb332467c8a3c596f6 Mon Sep 17 00:00:00 2001 From: Rahaf Date: Tue, 16 Jun 2026 13:59:17 +0300 Subject: [PATCH] Added terms with api --- app/terms/page.js | 281 +++++++++++++++++++++++++++++++++++----------- app/utils/api.js | 16 ++- 2 files changed, 224 insertions(+), 73 deletions(-) diff --git a/app/terms/page.js b/app/terms/page.js index 4f64b52..2921aa1 100644 --- a/app/terms/page.js +++ b/app/terms/page.js @@ -1,62 +1,143 @@ 'use client'; -import { useState, useEffect } from 'react'; +import { useEffect, useState } from 'react'; import { motion } from 'framer-motion'; -import { FileText, Shield, CheckCircle } from 'lucide-react'; -import { getTerms } from '../utils/api'; +import { FileText, Shield, CheckCircle, Languages, Loader2, AlertCircle } from 'lucide-react'; +import { getARTerms, getENTerms } from '../utils/api'; -const staticTerms = [ - { - title: 'مقدمة', - content: - 'مرحباً بك في منصة SweetHome. باستخدامك للمنصة، فإنك توافق على الالتزام بشروط الاستخدام هذه. إذا كنت لا توافق على أي جزء من هذه الشروط، يرجى عدم استخدام المنصة. تحتفظ المنصة بحق تعديل هذه الشروط في أي وقت مع إشعار المستخدمين.', +const containerVariants = { + hidden: { opacity: 0 }, + visible: { + opacity: 1, + transition: { staggerChildren: 0.08 }, }, - { - title: 'استخدام المنصة', - content: - 'يُسمح باستخدام المنصة للأغراض المشروعة فقط. يلتزم المستخدم بعدم استخدام المنصة في أي نشاط غير قانوني أو مخالف للقوانين السارية. كما يلتزم المستخدم بعدم محاولة الوصول غير المصرح به إلى أي جزء من المنصة أو الخوادم أو الأنظمة المتصلة بها.', - }, - { - title: 'حقوق ومسؤوليات المالك', - content: - 'يتحمل المالك مسؤولية دقة المعلومات المقدمة عن العقار بما في ذلك الصور والوصف والسعر والتوفر. يلتزم المالك بتحديث معلومات العقار بشكل دوري. المنصة غير مسؤولة عن أي نزاعات تنشأ بين المالك والمستأجر. يجب على المالك الالتزام بجميع القوانين المحلية المتعلقة بتأجير العقارات.', - }, - { - title: 'حقوق ومسؤوليات المستأجر', - content: - 'يلتزم المستأجر باستخدام العقار بطريقة مسؤولة وعدم التسبب في أي ضرر للممتلكات. يجب على المستأجر الالتزام بقوانين المنزل ومواعيد تسجيل الوصول والمغادرة. المنصة غير مسؤولة عن أي سلوك غير لائق من قبل المستأجرين.', - }, - { - title: 'الدفع والعمولات', - content: - 'تتقاضى المنصة عمولة على كل حصة ناجحة وفقاً للنسبة المحددة في وقت الحجز. جميع المدفوعات تتم عبر قنوات الدفع الآمنة في المنصة. أي رسوم إلغاء أو استرداد تخضع لسياسة الإلغاء المحددة في كل عقار.', - }, - { - title: 'خصوصية البيانات', - content: - 'نحن نأخذ خصوصية بياناتك على محمل الجد. يتم جمع واستخدام البيانات الشخصية وفقاً لسياسة الخصوصية الخاصة بنا. نحن لا نشارك معلوماتك مع أطراف ثالثة دون موافقتك، إلا عندما يقتضي القانون ذلك.', - }, -]; +}; + +const itemVariants = { + hidden: { opacity: 0, y: 24 }, + visible: { opacity: 1, y: 0 }, +}; + +const FALLBACK_TERMS = { + ar: [ + { + title: 'مقدمة', + description: + 'مرحباً بك في منصة SweetHome. باستخدامك للمنصة، فإنك توافق على الالتزام بشروط الاستخدام هذه. إذا كنت لا توافق على أي جزء من هذه الشروط، يرجى عدم استخدام المنصة.', + }, + { + title: 'استخدام المنصة', + description: + 'يُسمح باستخدام المنصة للأغراض المشروعة فقط. يلتزم المستخدم بعدم استخدام المنصة في أي نشاط غير قانوني.', + }, + { + title: 'حقوق ومسؤوليات المالك', + description: + 'يتحمل المالك مسؤولية دقة المعلومات المقدمة عن العقار بما في ذلك الصور والوصف والسعر والتوفر.', + }, + { + title: 'حقوق ومسؤوليات المستأجر', + description: + 'يلتزم المستأجر باستخدام العقار بطريقة مسؤولة وعدم التسبب في أي ضرر للممتلكات.', + }, + { + title: 'الدفع والعمولات', + description: + 'تتقاضى المنصة عمولة على كل حصة ناجحة وفقاً للنسبة المحددة في وقت الحجز.', + }, + { + title: 'خصوصية البيانات', + description: + 'نحن نأخذ خصوصية بياناتك على محمل الجد. يتم جمع واستخدام البيانات الشخصية وفقاً لسياسة الخصوصية الخاصة بنا.', + }, + ], + en: [ + { + title: 'Introduction', + description: + 'Welcome to SweetHome. By using our platform, you agree to comply with these terms. If you do not agree, please do not use the platform.', + }, + { + title: 'Platform Usage', + description: + 'The platform may only be used for lawful purposes. Users must not engage in any illegal activity.', + }, + { + title: 'Owner Rights & Responsibilities', + description: + 'Owners are responsible for the accuracy of property information including images, description, price, and availability.', + }, + { + title: 'Tenant Rights & Responsibilities', + description: + 'Tenants must use the property responsibly and not cause any damage to the property.', + }, + { + title: 'Payment & Commissions', + description: + 'The platform charges a commission on each successful booking according to the rate specified at the time of booking.', + }, + { + title: 'Data Privacy', + description: + 'We take your data privacy seriously. Personal data is collected and used in accordance with our Privacy Policy.', + }, + ], +}; export default function TermsPage() { - const [terms, setTerms] = useState(staticTerms); + const [terms, setTerms] = useState([]); + const [language, setLanguage] = useState('ar'); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(''); useEffect(() => { - async function fetchTerms() { + const controller = new AbortController(); + + const fetchTerms = async () => { try { - const data = await getTerms(); - if (data && Array.isArray(data) && data.length > 0) { - setTerms(data); + setLoading(true); + setError(''); + + const fetcher = language === 'ar' ? getARTerms : getENTerms; + const data = await fetcher(); + + if (!data) { + setTerms(FALLBACK_TERMS[language]); + return; } + + const raw = Array.isArray(data) ? data : data.terms || data.items || data.data || []; + + if (!Array.isArray(raw) || raw.length === 0) { + setTerms(FALLBACK_TERMS[language]); + return; + } + + const mapped = raw.map((item) => ({ + title: item.title || item.name || '', + description: item.description || item.content || item.body || item.text || '', + })); + + setTerms(mapped); } catch { - // fall back to static terms + setTerms(FALLBACK_TERMS[language]); + setError(''); + } finally { + setLoading(false); } - } + }; + fetchTerms(); - }, []); + + return () => controller.abort(); + }, [language]); return ( -
+
-

شروط الاستخدام

+ +
+

+ {language === 'ar' ? 'شروط الاستخدام' : 'Terms of Use'} +

+ +
+

- يرجى قراءة شروط الاستخدام التالية بعناية قبل استخدام المنصة + {language === 'ar' + ? 'يرجى قراءة شروط الاستخدام التالية بعناية قبل استخدام المنصة' + : 'Please read the following terms of use carefully before using the platform'}

-
- {terms.map((term, index) => ( - -
-
- + {loading && ( +
+ + + {language === 'ar' + ? 'جاري تحميل شروط الاستخدام...' + : 'Loading terms of use...'} + +
+ )} + + {error && ( + + + {error} + + )} + + {!loading && terms.length === 0 && !error && ( + + +

+ {language === 'ar' + ? 'لا توجد شروط استخدام متاحة حالياً' + : 'No terms of use available'} +

+
+ )} + + {terms.length > 0 && ( + + {terms.map((term, index) => ( + +
+
+ +
+
+ {term.title && ( +

{term.title}

+ )} +

+ {term.description} +

+
-
-

{term.title}

-

{term.content}

-
-
- - ))} -
+
+ ))} + + )}
-

آخر تحديث

+

+ {language === 'ar' ? 'آخر تحديث' : 'Last Updated'} +

- تم آخر تحديث لشروط الاستخدام في 1 مايو 2026. يرجى مراجعة هذه الصفحة بشكل دوري للاطلاع على أي تغييرات. + {language === 'ar' + ? 'تم آخر تحديث لشروط الاستخدام في 1 مايو 2026. يرجى مراجعة هذه الصفحة بشكل دوري للاطلاع على أي تغييرات.' + : 'Last updated on May 1, 2026. Please review this page periodically for any changes.'}

diff --git a/app/utils/api.js b/app/utils/api.js index 8155fb4..42b85a3 100644 --- a/app/utils/api.js +++ b/app/utils/api.js @@ -704,8 +704,12 @@ export async function bookReservation(propertyInfoId, startDate, endDate) { // ─── Terms ─── -export async function getTerms() { - return apiFetch('/Terms/GetTerms'); +export async function getARTerms() { + return apiFetch('/Configuration/GetARTerms'); +} + +export async function getENTerms() { + return apiFetch('/Configuration/GetENTerms'); } // ─── Profile ─── @@ -1151,11 +1155,11 @@ export async function updateSaleReport(id, data) { }); } -// ─── Terms (Add) ─── +// ─── Terms (Add or Update) ─── -export async function addTerm(name, description) { - return apiFetch('/Terms', { +export async function addOrUpdateTerms(terms) { + return apiFetch('/Terms/AddOrUpdateTerms', { method: 'POST', - body: { name, description }, + body: terms, }); } \ No newline at end of file