From c14c28141fa21e4920038796113205e9c566e926 Mon Sep 17 00:00:00 2001 From: Claw AI Date: Sat, 28 Mar 2026 16:12:21 +0000 Subject: [PATCH] Add loading.js and error.js for all routes, secure admin page with 404 - Added loading.js (dark/light variants) for all 14 routes - Added error.js (dark/light variants) for all 14 routes - Added global not-found.js and loading.js at root - Admin page shows 404 illustration for non-admin users instead of redirecting --- app/admin/error.js | 27 ++++++++++++++ app/admin/loading.js | 14 ++++++++ app/admin/page.js | 56 +++++++++++++++++++++++++---- app/auth/choose-role/error.js | 27 ++++++++++++++ app/auth/choose-role/loading.js | 14 ++++++++ app/error.js | 39 ++++++++++++++++++++ app/forgot-password/error.js | 27 ++++++++++++++ app/forgot-password/loading.js | 14 ++++++++ app/loading.js | 18 ++++++++++ app/login/error.js | 27 ++++++++++++++ app/login/loading.js | 14 ++++++++ app/not-found.js | 36 +++++++++++++++++++ app/owner/bookings/error.js | 27 ++++++++++++++ app/owner/bookings/loading.js | 14 ++++++++ app/owner/calendar/error.js | 27 ++++++++++++++ app/owner/calendar/loading.js | 14 ++++++++ app/owner/profits/error.js | 27 ++++++++++++++ app/owner/profits/loading.js | 14 ++++++++ app/owner/properties/add/error.js | 27 ++++++++++++++ app/owner/properties/add/loading.js | 14 ++++++++ app/owner/properties/error.js | 27 ++++++++++++++ app/owner/properties/loading.js | 14 ++++++++ app/profile/error.js | 27 ++++++++++++++ app/profile/loading.js | 14 ++++++++ app/properties/error.js | 27 ++++++++++++++ app/properties/loading.js | 14 ++++++++ app/property/[id]/error.js | 27 ++++++++++++++ app/property/[id]/loading.js | 14 ++++++++ app/register/owner/error.js | 27 ++++++++++++++ app/register/owner/loading.js | 14 ++++++++ app/register/tenant/error.js | 27 ++++++++++++++ app/register/tenant/loading.js | 14 ++++++++ 32 files changed, 716 insertions(+), 7 deletions(-) create mode 100644 app/admin/error.js create mode 100644 app/admin/loading.js create mode 100644 app/auth/choose-role/error.js create mode 100644 app/auth/choose-role/loading.js create mode 100644 app/error.js create mode 100644 app/forgot-password/error.js create mode 100644 app/forgot-password/loading.js create mode 100644 app/loading.js create mode 100644 app/login/error.js create mode 100644 app/login/loading.js create mode 100644 app/not-found.js create mode 100644 app/owner/bookings/error.js create mode 100644 app/owner/bookings/loading.js create mode 100644 app/owner/calendar/error.js create mode 100644 app/owner/calendar/loading.js create mode 100644 app/owner/profits/error.js create mode 100644 app/owner/profits/loading.js create mode 100644 app/owner/properties/add/error.js create mode 100644 app/owner/properties/add/loading.js create mode 100644 app/owner/properties/error.js create mode 100644 app/owner/properties/loading.js create mode 100644 app/profile/error.js create mode 100644 app/profile/loading.js create mode 100644 app/properties/error.js create mode 100644 app/properties/loading.js create mode 100644 app/property/[id]/error.js create mode 100644 app/property/[id]/loading.js create mode 100644 app/register/owner/error.js create mode 100644 app/register/owner/loading.js create mode 100644 app/register/tenant/error.js create mode 100644 app/register/tenant/loading.js diff --git a/app/admin/error.js b/app/admin/error.js new file mode 100644 index 0000000..a88abe0 --- /dev/null +++ b/app/admin/error.js @@ -0,0 +1,27 @@ +'use client'; + +import { motion } from 'framer-motion'; +import { AlertTriangle, RefreshCw, Home } from 'lucide-react'; +import Link from 'next/link'; + +export default function Error({ error, reset }) { + return ( +
+ +
+ +
+

حدث خطأ

+

نعتذر، حدث خطأ أثناء تحميل الصفحة

+
+ + + الرئيسية + +
+
+
+ ); +} diff --git a/app/admin/loading.js b/app/admin/loading.js new file mode 100644 index 0000000..0c01106 --- /dev/null +++ b/app/admin/loading.js @@ -0,0 +1,14 @@ +'use client'; + +import { motion } from 'framer-motion'; + +export default function Loading() { + return ( +
+ +
+

جاري التحميل...

+ +
+ ); +} diff --git a/app/admin/page.js b/app/admin/page.js index 50c0cb3..007988d 100644 --- a/app/admin/page.js +++ b/app/admin/page.js @@ -2,15 +2,16 @@ import { motion } from 'framer-motion'; import { useState, useEffect } from 'react'; -import { useRouter } from 'next/navigation'; import { useTranslation } from 'react-i18next'; +import Link from 'next/link'; import { Home, Calendar, Users, DollarSign, TrendingUp, - Bell + Bell, + Frown } from 'lucide-react'; import DashboardStats from '../components/admin/DashboardStats'; import PropertiesTable from '../components/admin/PropertiesTable'; @@ -24,16 +25,57 @@ import '../i18n/config'; export default function AdminPage() { const { t, i18n } = useTranslation(); - const router = useRouter(); const [activeTab, setActiveTab] = useState('dashboard'); const [showAddProperty, setShowAddProperty] = useState(false); const [notifications, setNotifications] = useState(3); + const [isAdmin, setIsAdmin] = useState(false); + const [checked, setChecked] = useState(false); useEffect(() => { - if (!AuthService.isAuthenticated() || !AuthService.isAdmin()) { - router.push('/'); - } - }, [router]); + setIsAdmin(AuthService.isAuthenticated() && AuthService.isAdmin()); + setChecked(true); + }, []); + + // ─── 404 for non-admins ─── + if (checked && !isAdmin) { + return ( +
+ +
+ + + + + + عذراً! + الصفحة غير موجودة + +
+

404 - الصفحة غير موجودة

+

عذراً، لا يمكنك الوصول إلى هذه الصفحة

+ + + العودة للرئيسية + +
+
+ ); + } + + if (!checked) { + return ( +
+
+
+ ); + } const tabs = [ { id: 'dashboard', label: 'لوحة التحكم', icon: Home }, diff --git a/app/auth/choose-role/error.js b/app/auth/choose-role/error.js new file mode 100644 index 0000000..a88abe0 --- /dev/null +++ b/app/auth/choose-role/error.js @@ -0,0 +1,27 @@ +'use client'; + +import { motion } from 'framer-motion'; +import { AlertTriangle, RefreshCw, Home } from 'lucide-react'; +import Link from 'next/link'; + +export default function Error({ error, reset }) { + return ( +
+ +
+ +
+

حدث خطأ

+

نعتذر، حدث خطأ أثناء تحميل الصفحة

+
+ + + الرئيسية + +
+
+
+ ); +} diff --git a/app/auth/choose-role/loading.js b/app/auth/choose-role/loading.js new file mode 100644 index 0000000..0c01106 --- /dev/null +++ b/app/auth/choose-role/loading.js @@ -0,0 +1,14 @@ +'use client'; + +import { motion } from 'framer-motion'; + +export default function Loading() { + return ( +
+ +
+

جاري التحميل...

+ +
+ ); +} diff --git a/app/error.js b/app/error.js new file mode 100644 index 0000000..6cf1deb --- /dev/null +++ b/app/error.js @@ -0,0 +1,39 @@ +'use client'; + +import { motion } from 'framer-motion'; +import { AlertTriangle, RefreshCw, Home } from 'lucide-react'; +import Link from 'next/link'; + +export default function GlobalError({ error, reset }) { + return ( +
+ +
+ +
+

حدث خطأ غير متوقع

+

نعتذر عن هذا الإزعاج، يرجى المحاولة مرة أخرى

+
+ + + + الرئيسية + +
+
+
+ ); +} diff --git a/app/forgot-password/error.js b/app/forgot-password/error.js new file mode 100644 index 0000000..a88abe0 --- /dev/null +++ b/app/forgot-password/error.js @@ -0,0 +1,27 @@ +'use client'; + +import { motion } from 'framer-motion'; +import { AlertTriangle, RefreshCw, Home } from 'lucide-react'; +import Link from 'next/link'; + +export default function Error({ error, reset }) { + return ( +
+ +
+ +
+

حدث خطأ

+

نعتذر، حدث خطأ أثناء تحميل الصفحة

+
+ + + الرئيسية + +
+
+
+ ); +} diff --git a/app/forgot-password/loading.js b/app/forgot-password/loading.js new file mode 100644 index 0000000..0c01106 --- /dev/null +++ b/app/forgot-password/loading.js @@ -0,0 +1,14 @@ +'use client'; + +import { motion } from 'framer-motion'; + +export default function Loading() { + return ( +
+ +
+

جاري التحميل...

+ +
+ ); +} diff --git a/app/loading.js b/app/loading.js new file mode 100644 index 0000000..2fee9e8 --- /dev/null +++ b/app/loading.js @@ -0,0 +1,18 @@ +'use client'; + +import { motion } from 'framer-motion'; + +export default function Loading() { + return ( +
+ +
+

جاري التحميل...

+ +
+ ); +} diff --git a/app/login/error.js b/app/login/error.js new file mode 100644 index 0000000..a88abe0 --- /dev/null +++ b/app/login/error.js @@ -0,0 +1,27 @@ +'use client'; + +import { motion } from 'framer-motion'; +import { AlertTriangle, RefreshCw, Home } from 'lucide-react'; +import Link from 'next/link'; + +export default function Error({ error, reset }) { + return ( +
+ +
+ +
+

حدث خطأ

+

نعتذر، حدث خطأ أثناء تحميل الصفحة

+
+ + + الرئيسية + +
+
+
+ ); +} diff --git a/app/login/loading.js b/app/login/loading.js new file mode 100644 index 0000000..0c01106 --- /dev/null +++ b/app/login/loading.js @@ -0,0 +1,14 @@ +'use client'; + +import { motion } from 'framer-motion'; + +export default function Loading() { + return ( +
+ +
+

جاري التحميل...

+ +
+ ); +} diff --git a/app/not-found.js b/app/not-found.js new file mode 100644 index 0000000..7c03916 --- /dev/null +++ b/app/not-found.js @@ -0,0 +1,36 @@ +'use client'; + +import { motion } from 'framer-motion'; +import { AlertTriangle, RefreshCw, Home } from 'lucide-react'; +import Link from 'next/link'; + +export default function NotFound() { + return ( +
+ +
+ + + 404 + + + + +
+

الصفحة غير موجودة

+

عذراً، الصفحة التي تبحث عنها غير متوفرة

+ + + العودة للرئيسية + +
+
+ ); +} diff --git a/app/owner/bookings/error.js b/app/owner/bookings/error.js new file mode 100644 index 0000000..a88abe0 --- /dev/null +++ b/app/owner/bookings/error.js @@ -0,0 +1,27 @@ +'use client'; + +import { motion } from 'framer-motion'; +import { AlertTriangle, RefreshCw, Home } from 'lucide-react'; +import Link from 'next/link'; + +export default function Error({ error, reset }) { + return ( +
+ +
+ +
+

حدث خطأ

+

نعتذر، حدث خطأ أثناء تحميل الصفحة

+
+ + + الرئيسية + +
+
+
+ ); +} diff --git a/app/owner/bookings/loading.js b/app/owner/bookings/loading.js new file mode 100644 index 0000000..0c01106 --- /dev/null +++ b/app/owner/bookings/loading.js @@ -0,0 +1,14 @@ +'use client'; + +import { motion } from 'framer-motion'; + +export default function Loading() { + return ( +
+ +
+

جاري التحميل...

+ +
+ ); +} diff --git a/app/owner/calendar/error.js b/app/owner/calendar/error.js new file mode 100644 index 0000000..a88abe0 --- /dev/null +++ b/app/owner/calendar/error.js @@ -0,0 +1,27 @@ +'use client'; + +import { motion } from 'framer-motion'; +import { AlertTriangle, RefreshCw, Home } from 'lucide-react'; +import Link from 'next/link'; + +export default function Error({ error, reset }) { + return ( +
+ +
+ +
+

حدث خطأ

+

نعتذر، حدث خطأ أثناء تحميل الصفحة

+
+ + + الرئيسية + +
+
+
+ ); +} diff --git a/app/owner/calendar/loading.js b/app/owner/calendar/loading.js new file mode 100644 index 0000000..0c01106 --- /dev/null +++ b/app/owner/calendar/loading.js @@ -0,0 +1,14 @@ +'use client'; + +import { motion } from 'framer-motion'; + +export default function Loading() { + return ( +
+ +
+

جاري التحميل...

+ +
+ ); +} diff --git a/app/owner/profits/error.js b/app/owner/profits/error.js new file mode 100644 index 0000000..a88abe0 --- /dev/null +++ b/app/owner/profits/error.js @@ -0,0 +1,27 @@ +'use client'; + +import { motion } from 'framer-motion'; +import { AlertTriangle, RefreshCw, Home } from 'lucide-react'; +import Link from 'next/link'; + +export default function Error({ error, reset }) { + return ( +
+ +
+ +
+

حدث خطأ

+

نعتذر، حدث خطأ أثناء تحميل الصفحة

+
+ + + الرئيسية + +
+
+
+ ); +} diff --git a/app/owner/profits/loading.js b/app/owner/profits/loading.js new file mode 100644 index 0000000..0c01106 --- /dev/null +++ b/app/owner/profits/loading.js @@ -0,0 +1,14 @@ +'use client'; + +import { motion } from 'framer-motion'; + +export default function Loading() { + return ( +
+ +
+

جاري التحميل...

+ +
+ ); +} diff --git a/app/owner/properties/add/error.js b/app/owner/properties/add/error.js new file mode 100644 index 0000000..a88abe0 --- /dev/null +++ b/app/owner/properties/add/error.js @@ -0,0 +1,27 @@ +'use client'; + +import { motion } from 'framer-motion'; +import { AlertTriangle, RefreshCw, Home } from 'lucide-react'; +import Link from 'next/link'; + +export default function Error({ error, reset }) { + return ( +
+ +
+ +
+

حدث خطأ

+

نعتذر، حدث خطأ أثناء تحميل الصفحة

+
+ + + الرئيسية + +
+
+
+ ); +} diff --git a/app/owner/properties/add/loading.js b/app/owner/properties/add/loading.js new file mode 100644 index 0000000..0c01106 --- /dev/null +++ b/app/owner/properties/add/loading.js @@ -0,0 +1,14 @@ +'use client'; + +import { motion } from 'framer-motion'; + +export default function Loading() { + return ( +
+ +
+

جاري التحميل...

+ +
+ ); +} diff --git a/app/owner/properties/error.js b/app/owner/properties/error.js new file mode 100644 index 0000000..a88abe0 --- /dev/null +++ b/app/owner/properties/error.js @@ -0,0 +1,27 @@ +'use client'; + +import { motion } from 'framer-motion'; +import { AlertTriangle, RefreshCw, Home } from 'lucide-react'; +import Link from 'next/link'; + +export default function Error({ error, reset }) { + return ( +
+ +
+ +
+

حدث خطأ

+

نعتذر، حدث خطأ أثناء تحميل الصفحة

+
+ + + الرئيسية + +
+
+
+ ); +} diff --git a/app/owner/properties/loading.js b/app/owner/properties/loading.js new file mode 100644 index 0000000..0c01106 --- /dev/null +++ b/app/owner/properties/loading.js @@ -0,0 +1,14 @@ +'use client'; + +import { motion } from 'framer-motion'; + +export default function Loading() { + return ( +
+ +
+

جاري التحميل...

+ +
+ ); +} diff --git a/app/profile/error.js b/app/profile/error.js new file mode 100644 index 0000000..745ae1a --- /dev/null +++ b/app/profile/error.js @@ -0,0 +1,27 @@ +'use client'; + +import { motion } from 'framer-motion'; +import { AlertTriangle, RefreshCw, Home } from 'lucide-react'; +import Link from 'next/link'; + +export default function Error({ error, reset }) { + return ( +
+ +
+ +
+

حدث خطأ

+

نعتذر، حدث خطأ أثناء تحميل الصفحة

+
+ + + الرئيسية + +
+
+
+ ); +} diff --git a/app/profile/loading.js b/app/profile/loading.js new file mode 100644 index 0000000..af02e7b --- /dev/null +++ b/app/profile/loading.js @@ -0,0 +1,14 @@ +'use client'; + +import { motion } from 'framer-motion'; + +export default function Loading() { + return ( +
+ +
+

جاري التحميل...

+ +
+ ); +} diff --git a/app/properties/error.js b/app/properties/error.js new file mode 100644 index 0000000..745ae1a --- /dev/null +++ b/app/properties/error.js @@ -0,0 +1,27 @@ +'use client'; + +import { motion } from 'framer-motion'; +import { AlertTriangle, RefreshCw, Home } from 'lucide-react'; +import Link from 'next/link'; + +export default function Error({ error, reset }) { + return ( +
+ +
+ +
+

حدث خطأ

+

نعتذر، حدث خطأ أثناء تحميل الصفحة

+
+ + + الرئيسية + +
+
+
+ ); +} diff --git a/app/properties/loading.js b/app/properties/loading.js new file mode 100644 index 0000000..af02e7b --- /dev/null +++ b/app/properties/loading.js @@ -0,0 +1,14 @@ +'use client'; + +import { motion } from 'framer-motion'; + +export default function Loading() { + return ( +
+ +
+

جاري التحميل...

+ +
+ ); +} diff --git a/app/property/[id]/error.js b/app/property/[id]/error.js new file mode 100644 index 0000000..745ae1a --- /dev/null +++ b/app/property/[id]/error.js @@ -0,0 +1,27 @@ +'use client'; + +import { motion } from 'framer-motion'; +import { AlertTriangle, RefreshCw, Home } from 'lucide-react'; +import Link from 'next/link'; + +export default function Error({ error, reset }) { + return ( +
+ +
+ +
+

حدث خطأ

+

نعتذر، حدث خطأ أثناء تحميل الصفحة

+
+ + + الرئيسية + +
+
+
+ ); +} diff --git a/app/property/[id]/loading.js b/app/property/[id]/loading.js new file mode 100644 index 0000000..af02e7b --- /dev/null +++ b/app/property/[id]/loading.js @@ -0,0 +1,14 @@ +'use client'; + +import { motion } from 'framer-motion'; + +export default function Loading() { + return ( +
+ +
+

جاري التحميل...

+ +
+ ); +} diff --git a/app/register/owner/error.js b/app/register/owner/error.js new file mode 100644 index 0000000..a88abe0 --- /dev/null +++ b/app/register/owner/error.js @@ -0,0 +1,27 @@ +'use client'; + +import { motion } from 'framer-motion'; +import { AlertTriangle, RefreshCw, Home } from 'lucide-react'; +import Link from 'next/link'; + +export default function Error({ error, reset }) { + return ( +
+ +
+ +
+

حدث خطأ

+

نعتذر، حدث خطأ أثناء تحميل الصفحة

+
+ + + الرئيسية + +
+
+
+ ); +} diff --git a/app/register/owner/loading.js b/app/register/owner/loading.js new file mode 100644 index 0000000..0c01106 --- /dev/null +++ b/app/register/owner/loading.js @@ -0,0 +1,14 @@ +'use client'; + +import { motion } from 'framer-motion'; + +export default function Loading() { + return ( +
+ +
+

جاري التحميل...

+ +
+ ); +} diff --git a/app/register/tenant/error.js b/app/register/tenant/error.js new file mode 100644 index 0000000..a88abe0 --- /dev/null +++ b/app/register/tenant/error.js @@ -0,0 +1,27 @@ +'use client'; + +import { motion } from 'framer-motion'; +import { AlertTriangle, RefreshCw, Home } from 'lucide-react'; +import Link from 'next/link'; + +export default function Error({ error, reset }) { + return ( +
+ +
+ +
+

حدث خطأ

+

نعتذر، حدث خطأ أثناء تحميل الصفحة

+
+ + + الرئيسية + +
+
+
+ ); +} diff --git a/app/register/tenant/loading.js b/app/register/tenant/loading.js new file mode 100644 index 0000000..0c01106 --- /dev/null +++ b/app/register/tenant/loading.js @@ -0,0 +1,14 @@ +'use client'; + +import { motion } from 'framer-motion'; + +export default function Loading() { + return ( +
+ +
+

جاري التحميل...

+ +
+ ); +}