139 lines
4.4 KiB
JavaScript
139 lines
4.4 KiB
JavaScript
|
|
'use client';
|
||
|
|
|
||
|
|
import { motion } from 'framer-motion';
|
||
|
|
import { Users, Home, Calendar, DollarSign } from 'lucide-react';
|
||
|
|
import { useEffect, useState } from 'react';
|
||
|
|
|
||
|
|
export default function DashboardStats() {
|
||
|
|
const [stats, setStats] = useState({
|
||
|
|
totalUsers: 0,
|
||
|
|
totalProperties: 0,
|
||
|
|
activeBookings: 0,
|
||
|
|
totalRevenue: 0,
|
||
|
|
pendingRequests: 0,
|
||
|
|
availableProperties: 0
|
||
|
|
});
|
||
|
|
|
||
|
|
useEffect(() => {
|
||
|
|
setStats({
|
||
|
|
totalUsers: 156,
|
||
|
|
totalProperties: 89,
|
||
|
|
activeBookings: 34,
|
||
|
|
totalRevenue: 12500000,
|
||
|
|
pendingRequests: 12,
|
||
|
|
availableProperties: 45
|
||
|
|
});
|
||
|
|
}, []);
|
||
|
|
|
||
|
|
const formatNumber = (num) => {
|
||
|
|
return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
||
|
|
};
|
||
|
|
|
||
|
|
const formatCurrency = (amount) => {
|
||
|
|
return `${formatNumber(amount)} ل.س`;
|
||
|
|
};
|
||
|
|
|
||
|
|
const cards = [
|
||
|
|
{
|
||
|
|
title: 'إجمالي المستخدمين',
|
||
|
|
value: stats.totalUsers,
|
||
|
|
icon: Users,
|
||
|
|
color: 'from-blue-600 to-blue-700',
|
||
|
|
bgColor: 'bg-blue-100',
|
||
|
|
iconColor: 'text-blue-600'
|
||
|
|
},
|
||
|
|
{
|
||
|
|
title: 'إجمالي العقارات',
|
||
|
|
value: stats.totalProperties,
|
||
|
|
icon: Home,
|
||
|
|
color: 'from-emerald-600 to-emerald-700',
|
||
|
|
bgColor: 'bg-emerald-100',
|
||
|
|
iconColor: 'text-emerald-600'
|
||
|
|
},
|
||
|
|
{
|
||
|
|
title: 'الحجوزات النشطة',
|
||
|
|
value: stats.activeBookings,
|
||
|
|
icon: Calendar,
|
||
|
|
color: 'from-purple-600 to-purple-700',
|
||
|
|
bgColor: 'bg-purple-100',
|
||
|
|
iconColor: 'text-purple-600'
|
||
|
|
},
|
||
|
|
{
|
||
|
|
title: 'الإيرادات',
|
||
|
|
value: formatCurrency(stats.totalRevenue),
|
||
|
|
icon: DollarSign,
|
||
|
|
color: 'from-amber-600 to-amber-700',
|
||
|
|
bgColor: 'bg-amber-100',
|
||
|
|
iconColor: 'text-amber-600'
|
||
|
|
}
|
||
|
|
];
|
||
|
|
|
||
|
|
return (
|
||
|
|
<div className="space-y-6">
|
||
|
|
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
|
||
|
|
{cards.map((card, index) => {
|
||
|
|
const Icon = card.icon;
|
||
|
|
return (
|
||
|
|
<motion.div
|
||
|
|
key={card.title}
|
||
|
|
initial={{ opacity: 0, y: 20 }}
|
||
|
|
animate={{ opacity: 1, y: 0 }}
|
||
|
|
transition={{ delay: index * 0.1 }}
|
||
|
|
className={`bg-gradient-to-br ${card.color} text-white rounded-xl shadow-lg p-5`}
|
||
|
|
>
|
||
|
|
<div className="flex items-center justify-between mb-4">
|
||
|
|
<div className={`p-3 ${card.bgColor} bg-opacity-20 rounded-lg`}>
|
||
|
|
<Icon className="w-6 h-6" />
|
||
|
|
</div>
|
||
|
|
<div className="text-right">
|
||
|
|
<div className="text-2xl font-bold">{card.value}</div>
|
||
|
|
<div className="text-sm opacity-90">{card.title}</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
<div className="text-xs opacity-75">
|
||
|
|
آخر تحديث: الآن
|
||
|
|
</div>
|
||
|
|
</motion.div>
|
||
|
|
);
|
||
|
|
})}
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
|
||
|
|
<motion.div
|
||
|
|
initial={{ opacity: 0 }}
|
||
|
|
animate={{ opacity: 1 }}
|
||
|
|
transition={{ delay: 0.4 }}
|
||
|
|
className="bg-white border rounded-lg p-4"
|
||
|
|
>
|
||
|
|
<div className="text-sm text-gray-600 mb-1">طلبات حجز معلقة</div>
|
||
|
|
<div className="text-2xl font-bold text-yellow-600">{stats.pendingRequests}</div>
|
||
|
|
<div className="text-xs text-gray-500">بحاجة لموافقة</div>
|
||
|
|
</motion.div>
|
||
|
|
|
||
|
|
<motion.div
|
||
|
|
initial={{ opacity: 0 }}
|
||
|
|
animate={{ opacity: 1 }}
|
||
|
|
transition={{ delay: 0.5 }}
|
||
|
|
className="bg-white border rounded-lg p-4"
|
||
|
|
>
|
||
|
|
<div className="text-sm text-gray-600 mb-1">عقارات متاحة</div>
|
||
|
|
<div className="text-2xl font-bold text-green-600">{stats.availableProperties}</div>
|
||
|
|
<div className="text-xs text-gray-500">جاهزة للإيجار</div>
|
||
|
|
</motion.div>
|
||
|
|
|
||
|
|
<motion.div
|
||
|
|
initial={{ opacity: 0 }}
|
||
|
|
animate={{ opacity: 1 }}
|
||
|
|
transition={{ delay: 0.6 }}
|
||
|
|
className="bg-white border rounded-lg p-4"
|
||
|
|
>
|
||
|
|
<div className="text-sm text-gray-600 mb-1">نسبة الإشغال</div>
|
||
|
|
<div className="text-2xl font-bold text-blue-600">
|
||
|
|
{Math.round((stats.activeBookings / stats.totalProperties) * 100)}%
|
||
|
|
</div>
|
||
|
|
<div className="text-xs text-gray-500">من إجمالي العقارات</div>
|
||
|
|
</motion.div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
);
|
||
|
|
}
|