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 (
+
+
+
+ الصفحة غير موجودة
+ عذراً، الصفحة التي تبحث عنها غير متوفرة
+
+
+ العودة للرئيسية
+
+
+
+ );
+}
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 (
+
+
+
+ جاري التحميل...
+
+
+ );
+}