forked from amer2004/SweetHome
Added translation to all site with edit style
This commit is contained in:
@ -4,6 +4,7 @@ import { useState, useEffect } from 'react';
|
||||
import { motion, AnimatePresence } from 'framer-motion';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import Link from 'next/link';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import {
|
||||
Calendar,
|
||||
Home,
|
||||
@ -37,6 +38,7 @@ import AuthService from '../../services/AuthService';
|
||||
import Image from 'next/image';
|
||||
|
||||
const OwnerBookingCalendar = ({ property, onDateSelect, selectedDates }) => {
|
||||
const { t } = useTranslation();
|
||||
const [currentMonth, setCurrentMonth] = useState(new Date());
|
||||
const [hoverDate, setHoverDate] = useState(null);
|
||||
|
||||
@ -53,8 +55,13 @@ const OwnerBookingCalendar = ({ property, onDateSelect, selectedDates }) => {
|
||||
).getDay();
|
||||
|
||||
const monthNames = [
|
||||
'يناير', 'فبراير', 'مارس', 'إبريل', 'مايو', 'يونيو',
|
||||
'يوليو', 'أغسطس', 'سبتمبر', 'أكتوبر', 'نوفمبر', 'ديسمبر'
|
||||
t('january'), t('february'), t('march'), t('april'), t('may'), t('june'),
|
||||
t('july'), t('august'), t('september'), t('october'), t('november'), t('december')
|
||||
];
|
||||
|
||||
const dayNames = [
|
||||
t('dayFull.sunday'), t('dayFull.monday'), t('dayFull.tuesday'), t('dayFull.wednesday'),
|
||||
t('dayFull.thursday'), t('dayFull.friday'), t('dayFull.saturday')
|
||||
];
|
||||
|
||||
const isDateBooked = (date) => {
|
||||
@ -134,7 +141,6 @@ const OwnerBookingCalendar = ({ property, onDateSelect, selectedDates }) => {
|
||||
|
||||
return (
|
||||
<div className="bg-white rounded-2xl shadow-sm border border-gray-200 p-6">
|
||||
{/* رأس التقويم */}
|
||||
<div className="flex items-center justify-between mb-6">
|
||||
<button
|
||||
onClick={() => setCurrentMonth(new Date(currentMonth.getFullYear(), currentMonth.getMonth() - 1, 1))}
|
||||
@ -156,15 +162,10 @@ const OwnerBookingCalendar = ({ property, onDateSelect, selectedDates }) => {
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* أيام الأسبوع */}
|
||||
<div className="grid grid-cols-7 gap-1 mb-3 text-center text-sm font-medium text-gray-500">
|
||||
<div>أحد</div>
|
||||
<div>إثنين</div>
|
||||
<div>ثلاثاء</div>
|
||||
<div>أربعاء</div>
|
||||
<div>خميس</div>
|
||||
<div>جمعة</div>
|
||||
<div>سبت</div>
|
||||
{dayNames.map((name, i) => (
|
||||
<div key={i}>{name}</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-7 gap-1">
|
||||
@ -174,19 +175,19 @@ const OwnerBookingCalendar = ({ property, onDateSelect, selectedDates }) => {
|
||||
<div className="flex flex-wrap gap-4 mt-6 pt-4 border-t border-gray-200 text-xs">
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="w-3 h-3 bg-red-100 rounded" />
|
||||
<span className="text-gray-600">محجوز</span>
|
||||
<span className="text-gray-600">{t('booked')}</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="w-3 h-3 bg-amber-500 rounded" />
|
||||
<span className="text-gray-600">محدد</span>
|
||||
<span className="text-gray-600">{t('selected')}</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="w-3 h-3 bg-amber-100 rounded" />
|
||||
<span className="text-gray-600">ضمن الفترة</span>
|
||||
<span className="text-gray-600">{t('inRange')}</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="w-3 h-3 border-2 border-amber-500 rounded" />
|
||||
<span className="text-gray-600">اليوم</span>
|
||||
<span className="text-gray-600">{t('today')}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -194,16 +195,18 @@ const OwnerBookingCalendar = ({ property, onDateSelect, selectedDates }) => {
|
||||
};
|
||||
|
||||
const BookingCard = ({ booking, onViewDetails, onContact }) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const formatCurrency = (amount) => {
|
||||
return amount?.toLocaleString() + ' ل.س';
|
||||
return amount?.toLocaleString() + ' ' + t('syp');
|
||||
};
|
||||
|
||||
const getStatusBadge = (status) => {
|
||||
const statusConfig = {
|
||||
pending: { label: 'قيد الانتظار', color: 'bg-yellow-100 text-yellow-800', icon: Clock },
|
||||
confirmed: { label: 'مؤكد', color: 'bg-green-100 text-green-800', icon: CheckCircle },
|
||||
cancelled: { label: 'ملغي', color: 'bg-red-100 text-red-800', icon: XCircle },
|
||||
completed: { label: 'منتهي', color: 'bg-gray-100 text-gray-800', icon: CheckCircle }
|
||||
pending: { label: t('pending'), color: 'bg-yellow-100 text-yellow-800', icon: Clock },
|
||||
confirmed: { label: t('confirmed'), color: 'bg-green-100 text-green-800', icon: CheckCircle },
|
||||
cancelled: { label: t('cancelled'), color: 'bg-red-100 text-red-800', icon: XCircle },
|
||||
completed: { label: t('completed'), color: 'bg-gray-100 text-gray-800', icon: CheckCircle }
|
||||
};
|
||||
|
||||
const config = statusConfig[status] || statusConfig.pending;
|
||||
@ -237,7 +240,7 @@ const BookingCard = ({ booking, onViewDetails, onContact }) => {
|
||||
</div>
|
||||
<div className="text-left">
|
||||
<div className="text-lg font-bold text-amber-600">{formatCurrency(booking.totalAmount)}</div>
|
||||
<div className="text-xs text-gray-500">إجمالي المبلغ</div>
|
||||
<div className="text-xs text-gray-500">{t('totalAmount')}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -261,18 +264,18 @@ const BookingCard = ({ booking, onViewDetails, onContact }) => {
|
||||
<div className="grid grid-cols-3 gap-3 mb-4 text-center">
|
||||
<div className="bg-gray-50 p-2 rounded-lg">
|
||||
<Calendar className="w-4 h-4 text-amber-500 mx-auto mb-1" />
|
||||
<div className="text-xs text-gray-500">من</div>
|
||||
<div className="text-xs text-gray-500">{t('from')}</div>
|
||||
<div className="text-sm font-medium">{booking.startDate}</div>
|
||||
</div>
|
||||
<div className="bg-gray-50 p-2 rounded-lg">
|
||||
<Calendar className="w-4 h-4 text-amber-500 mx-auto mb-1" />
|
||||
<div className="text-xs text-gray-500">إلى</div>
|
||||
<div className="text-xs text-gray-500">{t('to')}</div>
|
||||
<div className="text-sm font-medium">{booking.endDate}</div>
|
||||
</div>
|
||||
<div className="bg-gray-50 p-2 rounded-lg">
|
||||
<Clock className="w-4 h-4 text-amber-500 mx-auto mb-1" />
|
||||
<div className="text-xs text-gray-500">المدة</div>
|
||||
<div className="text-sm font-medium">{booking.days} يوم</div>
|
||||
<div className="text-xs text-gray-500">{t('duration')}</div>
|
||||
<div className="text-sm font-medium">{booking.days} {t('days')}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -282,15 +285,8 @@ const BookingCard = ({ booking, onViewDetails, onContact }) => {
|
||||
className="flex-1 bg-gray-100 text-gray-700 py-2 rounded-xl text-sm font-medium hover:bg-gray-200 transition-colors flex items-center justify-center gap-2"
|
||||
>
|
||||
<Eye className="w-4 h-4" />
|
||||
التفاصيل
|
||||
{t('details')}
|
||||
</button>
|
||||
{/* <button
|
||||
onClick={() => onContact(booking)}
|
||||
className="flex-1 bg-amber-500 text-white py-2 rounded-xl text-sm font-medium hover:bg-amber-600 transition-colors flex items-center justify-center gap-2"
|
||||
>
|
||||
<MessageCircle className="w-4 h-4" />
|
||||
تواصل
|
||||
</button> */}
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
@ -298,10 +294,11 @@ const BookingCard = ({ booking, onViewDetails, onContact }) => {
|
||||
};
|
||||
|
||||
const BookingDetailsModal = ({ booking, isOpen, onClose }) => {
|
||||
const { t } = useTranslation();
|
||||
if (!isOpen || !booking) return null;
|
||||
|
||||
const formatCurrency = (amount) => {
|
||||
return amount?.toLocaleString() + ' ل.س';
|
||||
return amount?.toLocaleString() + ' ' + t('syp');
|
||||
};
|
||||
|
||||
return (
|
||||
@ -321,80 +318,80 @@ const BookingDetailsModal = ({ booking, isOpen, onClose }) => {
|
||||
>
|
||||
<div className="sticky top-0 bg-gradient-to-r from-amber-500 to-amber-600 p-6 text-white">
|
||||
<div className="flex justify-between items-center">
|
||||
<h2 className="text-xl font-bold">تفاصيل الحجز</h2>
|
||||
<h2 className="text-xl font-bold">{t('bookingDetails')}</h2>
|
||||
<button onClick={onClose} className="p-1 hover:bg-white/20 rounded-full">
|
||||
<XCircle className="w-6 h-6" />
|
||||
</button>
|
||||
</div>
|
||||
<p className="text-amber-100 text-sm mt-1">رقم الحجز: #{booking.id}</p>
|
||||
<p className="text-amber-100 text-sm mt-1">{t('bookingId', { id: booking.id })}</p>
|
||||
</div>
|
||||
|
||||
<div className="p-6 space-y-6">
|
||||
<div className="bg-gray-50 p-4 rounded-xl">
|
||||
<h3 className="font-bold text-gray-900 mb-3">معلومات العقار</h3>
|
||||
<h3 className="font-bold text-gray-900 mb-3">{t('propertyInfo')}</h3>
|
||||
<div className="space-y-2">
|
||||
<p><span className="text-gray-500">العقار:</span> {booking.propertyTitle}</p>
|
||||
<p><span className="text-gray-500">الموقع:</span> {booking.location}</p>
|
||||
<p><span className="text-gray-500">{t('property')}:</span> {booking.propertyTitle}</p>
|
||||
<p><span className="text-gray-500">{t('location')}:</span> {booking.location}</p>
|
||||
{booking.propertyDetails && (
|
||||
<div className="flex gap-3 mt-2">
|
||||
<span className="text-sm bg-white px-2 py-1 rounded-lg">{booking.propertyDetails.bedrooms} غرف</span>
|
||||
<span className="text-sm bg-white px-2 py-1 rounded-lg">{booking.propertyDetails.bathrooms} حمامات</span>
|
||||
<span className="text-sm bg-white px-2 py-1 rounded-lg">{booking.propertyDetails.area} م²</span>
|
||||
<span className="text-sm bg-white px-2 py-1 rounded-lg">{booking.propertyDetails.bedrooms} {t('rooms')}</span>
|
||||
<span className="text-sm bg-white px-2 py-1 rounded-lg">{booking.propertyDetails.bathrooms} {t('bathrooms')}</span>
|
||||
<span className="text-sm bg-white px-2 py-1 rounded-lg">{booking.propertyDetails.area} {t('sqm')}</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="bg-gray-50 p-4 rounded-xl">
|
||||
<h3 className="font-bold text-gray-900 mb-3">معلومات المستأجر</h3>
|
||||
<h3 className="font-bold text-gray-900 mb-3">{t('tenantInfo')}</h3>
|
||||
<div className="space-y-2">
|
||||
<p><span className="text-gray-500">الاسم:</span> {booking.tenantName}</p>
|
||||
<p><span className="text-gray-500">البريد الإلكتروني:</span> {booking.tenantEmail}</p>
|
||||
<p><span className="text-gray-500">رقم الهاتف:</span> {booking.tenantPhone}</p>
|
||||
<p><span className="text-gray-500">{t('name')}</span> {booking.tenantName}</p>
|
||||
<p><span className="text-gray-500">{t('email')}</span> {booking.tenantEmail}</p>
|
||||
<p><span className="text-gray-500">{t('phone')}</span> {booking.tenantPhone}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="bg-gray-50 p-4 rounded-xl">
|
||||
<h3 className="font-bold text-gray-900 mb-3">تفاصيل الحجز</h3>
|
||||
<h3 className="font-bold text-gray-900 mb-3">{t('bookingDetails')}</h3>
|
||||
<div className="grid grid-cols-2 gap-4">
|
||||
<div>
|
||||
<p className="text-gray-500">تاريخ البداية</p>
|
||||
<p className="text-gray-500">{t('startDate')}</p>
|
||||
<p className="font-medium">{booking.startDate}</p>
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-gray-500">تاريخ النهاية</p>
|
||||
<p className="text-gray-500">{t('endDate')}</p>
|
||||
<p className="font-medium">{booking.endDate}</p>
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-gray-500">عدد الأيام</p>
|
||||
<p className="font-medium">{booking.days} يوم</p>
|
||||
<p className="text-gray-500">{t('durationDays', { days: booking.days })}</p>
|
||||
<p className="font-medium">{booking.days} {t('days')}</p>
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-gray-500">حالة الحجز</p>
|
||||
<p className="font-medium">{booking.status === 'pending' ? 'قيد الانتظار' :
|
||||
booking.status === 'confirmed' ? 'مؤكد' :
|
||||
booking.status === 'cancelled' ? 'ملغي' : 'منتهي'}</p>
|
||||
<p className="text-gray-500">{t('bookingStatus')}</p>
|
||||
<p className="font-medium">{booking.status === 'pending' ? t('pending') :
|
||||
booking.status === 'confirmed' ? t('confirmed') :
|
||||
booking.status === 'cancelled' ? t('cancelled') : t('completed')}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="bg-amber-50 p-4 rounded-xl">
|
||||
<h3 className="font-bold text-amber-700 mb-3">المعلومات المالية</h3>
|
||||
<h3 className="font-bold text-amber-700 mb-3">{t('financialInfo')}</h3>
|
||||
<div className="space-y-2">
|
||||
<div className="flex justify-between">
|
||||
<span className="text-gray-600">السعر اليومي</span>
|
||||
<span className="text-gray-600">{t('dailyPrice')}</span>
|
||||
<span className="font-medium">{formatCurrency(booking.dailyPrice)}</span>
|
||||
</div>
|
||||
<div className="flex justify-between">
|
||||
<span className="text-gray-600">المدة ({booking.days} أيام)</span>
|
||||
<span className="text-gray-600">{t('durationDays', { days: booking.days })}</span>
|
||||
<span className="font-medium">{formatCurrency(booking.dailyPrice * booking.days)}</span>
|
||||
</div>
|
||||
<div className="flex justify-between">
|
||||
<span className="text-gray-600">سلفة الضمان</span>
|
||||
<span className="text-gray-600">{t('securityDeposit')}</span>
|
||||
<span className="font-medium">{formatCurrency(booking.securityDeposit || 0)}</span>
|
||||
</div>
|
||||
<div className="flex justify-between pt-2 border-t border-amber-200 font-bold">
|
||||
<span className="text-gray-900">الإجمالي</span>
|
||||
<span className="text-gray-900">{t('total')}</span>
|
||||
<span className="text-amber-600 text-lg">{formatCurrency(booking.totalAmount)}</span>
|
||||
</div>
|
||||
</div>
|
||||
@ -402,7 +399,7 @@ const BookingDetailsModal = ({ booking, isOpen, onClose }) => {
|
||||
|
||||
{booking.notes && (
|
||||
<div className="bg-gray-50 p-4 rounded-xl">
|
||||
<h3 className="font-bold text-gray-900 mb-2">ملاحظات</h3>
|
||||
<h3 className="font-bold text-gray-900 mb-2">{t('notes')}</h3>
|
||||
<p className="text-gray-600">{booking.notes}</p>
|
||||
</div>
|
||||
)}
|
||||
@ -413,6 +410,7 @@ const BookingDetailsModal = ({ booking, isOpen, onClose }) => {
|
||||
};
|
||||
|
||||
export default function OwnerBookingsPage() {
|
||||
const { t, i18n } = useTranslation();
|
||||
const router = useRouter();
|
||||
const [user, setUser] = useState(null);
|
||||
const [bookings, setBookings] = useState([]);
|
||||
@ -449,10 +447,10 @@ export default function OwnerBookingsPage() {
|
||||
{
|
||||
id: 'BK001',
|
||||
propertyId: 1,
|
||||
propertyTitle: 'فيلا فاخرة في المزة',
|
||||
location: 'دمشق، المزة',
|
||||
propertyTitle: t('ownerBookings.mockB1Title'),
|
||||
location: t('ownerBookings.mockB1Location'),
|
||||
propertyDetails: { bedrooms: 5, bathrooms: 4, area: 450 },
|
||||
tenantName: 'أحمد محمد',
|
||||
tenantName: t('ownerBookings.mockB1Tenant'),
|
||||
tenantEmail: 'ahmed@example.com',
|
||||
tenantPhone: '0933111222',
|
||||
startDate: '2024-03-10',
|
||||
@ -463,15 +461,15 @@ export default function OwnerBookingsPage() {
|
||||
securityDeposit: 500000,
|
||||
status: 'confirmed',
|
||||
createdAt: '2024-02-25',
|
||||
notes: 'طلب الحجز من خلال الموقع'
|
||||
notes: t('ownerBookings.mockB1Notes')
|
||||
},
|
||||
{
|
||||
id: 'BK002',
|
||||
propertyId: 2,
|
||||
propertyTitle: 'شقة حديثة في الشهباء',
|
||||
location: 'حلب، الشهباء',
|
||||
propertyTitle: t('ownerBookings.mockB2Title'),
|
||||
location: t('ownerBookings.mockB2Location'),
|
||||
propertyDetails: { bedrooms: 3, bathrooms: 2, area: 180 },
|
||||
tenantName: 'سارة أحمد',
|
||||
tenantName: t('ownerBookings.mockB2Tenant'),
|
||||
tenantEmail: 'sara@example.com',
|
||||
tenantPhone: '0945123789',
|
||||
startDate: '2024-03-05',
|
||||
@ -482,15 +480,15 @@ export default function OwnerBookingsPage() {
|
||||
securityDeposit: 250000,
|
||||
status: 'pending',
|
||||
createdAt: '2024-02-24',
|
||||
notes: 'تحتاج إلى تأكيد'
|
||||
notes: t('ownerBookings.mockB2Notes')
|
||||
},
|
||||
{
|
||||
id: 'BK003',
|
||||
propertyId: 3,
|
||||
propertyTitle: 'بيت عائلي في بابا عمرو',
|
||||
location: 'حمص، بابا عمرو',
|
||||
propertyTitle: t('ownerBookings.mockB3Title'),
|
||||
location: t('ownerBookings.mockB3Location'),
|
||||
propertyDetails: { bedrooms: 4, bathrooms: 3, area: 300 },
|
||||
tenantName: 'محمد الحلبي',
|
||||
tenantName: t('ownerBookings.mockB3Tenant'),
|
||||
tenantEmail: 'mohammed@example.com',
|
||||
tenantPhone: '0956123456',
|
||||
startDate: '2024-02-20',
|
||||
@ -501,7 +499,7 @@ export default function OwnerBookingsPage() {
|
||||
securityDeposit: 500000,
|
||||
status: 'completed',
|
||||
createdAt: '2024-02-15',
|
||||
notes: 'تم إنهاء الإيجار بنجاح'
|
||||
notes: t('ownerBookings.mockB3Notes')
|
||||
}
|
||||
];
|
||||
setBookings(mockBookings);
|
||||
@ -518,7 +516,7 @@ export default function OwnerBookingsPage() {
|
||||
};
|
||||
|
||||
const handleContact = (booking) => {
|
||||
toast.success(`جاري فتح محادثة مع ${booking.tenantName}`, {
|
||||
toast.success(t('openingChat', { name: booking.tenantName }), {
|
||||
icon: '💬',
|
||||
style: { background: '#dcfce7', color: '#166534' }
|
||||
});
|
||||
@ -531,7 +529,7 @@ export default function OwnerBookingsPage() {
|
||||
setBookings(updatedBookings);
|
||||
setFilteredBookings(updatedBookings);
|
||||
localStorage.setItem('ownerBookings', JSON.stringify(updatedBookings));
|
||||
toast.success(`تم تحديث حالة الحجز بنجاح`);
|
||||
toast.success(t('statusUpdated'));
|
||||
};
|
||||
|
||||
const statusCounts = {
|
||||
@ -547,14 +545,14 @@ export default function OwnerBookingsPage() {
|
||||
<div className="min-h-screen bg-gray-50 flex items-center justify-center">
|
||||
<div className="text-center">
|
||||
<Loader2 className="w-12 h-12 text-amber-500 animate-spin mx-auto mb-4" />
|
||||
<p className="text-gray-600">جاري تحميل الحجوزات...</p>
|
||||
<p className="text-gray-600">{t('loading')}</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-gray-50 py-8">
|
||||
<div className="min-h-screen bg-gray-50 py-8" dir={i18n.language === 'ar' ? 'rtl' : 'ltr'}>
|
||||
<Toaster position="top-center" reverseOrder={false} />
|
||||
|
||||
<BookingDetailsModal
|
||||
@ -570,8 +568,8 @@ export default function OwnerBookingsPage() {
|
||||
className="flex flex-col md:flex-row justify-between items-start md:items-center mb-8 gap-4"
|
||||
>
|
||||
<div>
|
||||
<h1 className="text-3xl font-bold text-gray-900 mb-2">حجوزاتي</h1>
|
||||
<p className="text-gray-600">مرحباً {user?.name}، لديك {bookings.length} حجز</p>
|
||||
<h1 className="text-3xl font-bold text-gray-900 mb-2">{t('myBookings')}</h1>
|
||||
<p className="text-gray-600">{t('welcomeBookings', { name: user?.name, count: bookings.length })}</p>
|
||||
</div>
|
||||
|
||||
<div className="flex gap-3">
|
||||
@ -580,12 +578,8 @@ export default function OwnerBookingsPage() {
|
||||
className="px-4 py-2 bg-white border border-gray-300 rounded-xl text-gray-700 hover:bg-gray-50 transition-colors flex items-center gap-2"
|
||||
>
|
||||
<Calendar className="w-5 h-5" />
|
||||
{showCalendar ? 'إخفاء التقويم' : 'عرض التقويم'}
|
||||
{showCalendar ? t('hideCalendar') : t('showCalendar')}
|
||||
</button>
|
||||
{/* <button className="px-4 py-2 bg-green-600 text-white rounded-xl hover:bg-green-700 transition-colors flex items-center gap-2">
|
||||
<Download className="w-5 h-5" />
|
||||
تصدير التقرير
|
||||
</button> */}
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
@ -598,7 +592,7 @@ export default function OwnerBookingsPage() {
|
||||
onClick={() => setFilterStatus('all')}
|
||||
>
|
||||
<div className="text-2xl font-bold text-gray-900">{statusCounts.all}</div>
|
||||
<div className="text-sm text-gray-600">جميع الحجوزات</div>
|
||||
<div className="text-sm text-gray-600">{t('allBookings')}</div>
|
||||
</motion.div>
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
@ -610,7 +604,7 @@ export default function OwnerBookingsPage() {
|
||||
onClick={() => setFilterStatus('pending')}
|
||||
>
|
||||
<div className="text-2xl font-bold text-yellow-600">{statusCounts.pending}</div>
|
||||
<div className="text-sm text-gray-600">قيد الانتظار</div>
|
||||
<div className="text-sm text-gray-600">{t('pending')}</div>
|
||||
</motion.div>
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
@ -622,7 +616,7 @@ export default function OwnerBookingsPage() {
|
||||
onClick={() => setFilterStatus('confirmed')}
|
||||
>
|
||||
<div className="text-2xl font-bold text-green-600">{statusCounts.confirmed}</div>
|
||||
<div className="text-sm text-gray-600">مؤكدة</div>
|
||||
<div className="text-sm text-gray-600">{t('confirmed')}</div>
|
||||
</motion.div>
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
@ -634,7 +628,7 @@ export default function OwnerBookingsPage() {
|
||||
onClick={() => setFilterStatus('completed')}
|
||||
>
|
||||
<div className="text-2xl font-bold text-gray-600">{statusCounts.completed}</div>
|
||||
<div className="text-sm text-gray-600">منتهية</div>
|
||||
<div className="text-sm text-gray-600">{t('completed')}</div>
|
||||
</motion.div>
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
@ -646,7 +640,7 @@ export default function OwnerBookingsPage() {
|
||||
onClick={() => setFilterStatus('cancelled')}
|
||||
>
|
||||
<div className="text-2xl font-bold text-red-600">{statusCounts.cancelled}</div>
|
||||
<div className="text-sm text-gray-600">ملغية</div>
|
||||
<div className="text-sm text-gray-600">{t('cancelled')}</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
|
||||
@ -655,7 +649,7 @@ export default function OwnerBookingsPage() {
|
||||
<Search className="absolute left-3 top-1/2 transform -translate-y-1/2 w-5 h-5 text-gray-400" />
|
||||
<input
|
||||
type="text"
|
||||
placeholder="ابحث باسم العقار أو المستأجر.."
|
||||
placeholder={t('searchBookings')}
|
||||
value={searchTerm}
|
||||
onChange={(e) => setSearchTerm(e.target.value)}
|
||||
className="w-full pl-10 pr-4 py-3 border border-gray-300 rounded-xl focus:outline-none focus:ring-2 focus:ring-amber-500"
|
||||
@ -667,21 +661,21 @@ export default function OwnerBookingsPage() {
|
||||
value={dateRange.start}
|
||||
onChange={(e) => setDateRange({...dateRange, start: e.target.value})}
|
||||
className="px-4 py-3 border border-gray-300 rounded-xl focus:outline-none focus:ring-2 focus:ring-amber-500"
|
||||
placeholder="من تاريخ"
|
||||
placeholder={t('filterDateFrom')}
|
||||
/>
|
||||
<input
|
||||
type="date"
|
||||
value={dateRange.end}
|
||||
onChange={(e) => setDateRange({...dateRange, end: e.target.value})}
|
||||
className="px-4 py-3 border border-gray-300 rounded-xl focus:outline-none focus:ring-2 focus:ring-amber-500"
|
||||
placeholder="إلى تاريخ"
|
||||
placeholder={t('filterDateTo')}
|
||||
/>
|
||||
{(dateRange.start || dateRange.end) && (
|
||||
<button
|
||||
onClick={() => setDateRange({ start: '', end: '' })}
|
||||
className="px-4 py-3 bg-gray-100 text-gray-700 rounded-xl hover:bg-gray-200 transition-colors"
|
||||
>
|
||||
مسح
|
||||
{t('clear')}
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
@ -708,16 +702,16 @@ export default function OwnerBookingsPage() {
|
||||
<div className="w-24 h-24 bg-amber-100 rounded-full flex items-center justify-center mx-auto mb-4">
|
||||
<Calendar className="w-12 h-12 text-amber-600" />
|
||||
</div>
|
||||
<h3 className="text-xl font-bold text-gray-900 mb-2">لا توجد حجوزات</h3>
|
||||
<h3 className="text-xl font-bold text-gray-900 mb-2">{t('noBookings')}</h3>
|
||||
<p className="text-gray-600 mb-4">
|
||||
{filterStatus !== 'all' ? 'لا توجد حجوزات في هذه الفئة' : 'لم يتم استلام أي حجوزات بعد'}
|
||||
{filterStatus !== 'all' ? t('noBookingsInCategory') : t('noBookingsReceived')}
|
||||
</p>
|
||||
{filterStatus !== 'all' && (
|
||||
<button
|
||||
onClick={() => setFilterStatus('all')}
|
||||
className="inline-flex items-center gap-2 bg-amber-500 text-white px-6 py-3 rounded-xl font-medium hover:bg-amber-600"
|
||||
>
|
||||
عرض جميع الحجوزات
|
||||
{t('viewAllBookings')}
|
||||
</button>
|
||||
)}
|
||||
</motion.div>
|
||||
@ -736,4 +730,4 @@ export default function OwnerBookingsPage() {
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user