fixed payment ,colors , add Mosque distance and fixed some elemnent
All checks were successful
Build frontend / build (push) Successful in 1m7s
All checks were successful
Build frontend / build (push) Successful in 1m7s
This commit is contained in:
@ -24,12 +24,12 @@ export default function BottomNav({ isOwner, isOwnerOrAgent }) {
|
|||||||
...(isOwnerOrAgent
|
...(isOwnerOrAgent
|
||||||
? [
|
? [
|
||||||
{ href: "/owner/properties", label: t("myProperties"), icon: Building },
|
{ href: "/owner/properties", label: t("myProperties"), icon: Building },
|
||||||
{ href: "/owner/bookings", label: "عقاراتي المحجوزة", icon: CalendarCheck },
|
{ href: "/owner/bookings", label: t("Myseizedproperties"), icon: CalendarCheck },
|
||||||
{ href: "/reservations", label: "حجوزاتي", icon: CalendarDays },
|
{ href: "/reservations", label: t("Mybookings"), icon: CalendarDays },
|
||||||
]
|
]
|
||||||
: [{ href: "/booked-properties", label: "حجوزاتي", icon: CalendarDays }]),
|
: [{ href: "/booked-properties", label: t("Mybookings"), icon: CalendarDays }]),
|
||||||
|
|
||||||
{ href: bookingsHref, label: "طلبات الحجز", icon: ClipboardList },
|
{ href: bookingsHref, label: t("Orders"), icon: ClipboardList },
|
||||||
{ href: "/payments", label: t("payments"), icon: CreditCard },
|
{ href: "/payments", label: t("payments"), icon: CreditCard },
|
||||||
|
|
||||||
...(isOwnerOrAgent ? [{ href: "/owner/account-book", label: t("accountBook"), icon: BookOpenCheck }] : []),
|
...(isOwnerOrAgent ? [{ href: "/owner/account-book", label: t("accountBook"), icon: BookOpenCheck }] : []),
|
||||||
@ -61,20 +61,16 @@ export default function BottomNav({ isOwner, isOwnerOrAgent }) {
|
|||||||
<Link
|
<Link
|
||||||
key={it.href}
|
key={it.href}
|
||||||
href={it.href}
|
href={it.href}
|
||||||
style={{ padding: "3px", width: "100px" }}
|
style={{ padding: "3px", width: "115px" }}
|
||||||
className={`
|
className={`
|
||||||
|
|
||||||
flex
|
flex
|
||||||
flex-col
|
flex-col
|
||||||
items-center
|
items-center
|
||||||
justify-center
|
justify-center
|
||||||
rounded-xl
|
rounded-xl
|
||||||
|
|
||||||
transition-all
|
transition-all
|
||||||
duration-200
|
duration-200
|
||||||
ease-out
|
ease-out
|
||||||
|
|
||||||
|
|
||||||
${active ? "bg-white shadow-sm text-amber-600" : "text-gray-700 hover:bg-white/80 hover:text-amber-600 hover:shadow-md"}
|
${active ? "bg-white shadow-sm text-amber-600" : "text-gray-700 hover:bg-white/80 hover:text-amber-600 hover:shadow-md"}
|
||||||
`}
|
`}
|
||||||
>
|
>
|
||||||
@ -99,7 +95,7 @@ export default function BottomNav({ isOwner, isOwnerOrAgent }) {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="mt-0.5 text-[10px] sm:mt-1 sm:text-xs">{it.label}</div>
|
<div className="mt-0.5 text-[10px] sm:mt-1 text-center sm:text-xs">{it.label}</div>
|
||||||
</Link>
|
</Link>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
|||||||
@ -314,7 +314,9 @@ const resources = {
|
|||||||
|
|
||||||
/* ─── Bottom nav ─── */
|
/* ─── Bottom nav ─── */
|
||||||
payments: "Payments",
|
payments: "Payments",
|
||||||
|
Myseizedproperties:"Seized Properties",
|
||||||
|
Mybookings:"My bookings",
|
||||||
|
Orders:"Orders",
|
||||||
/* ─── Footer ─── */
|
/* ─── Footer ─── */
|
||||||
footerDescription: "Your trusted platform for finding and listing premium properties across Syria.",
|
footerDescription: "Your trusted platform for finding and listing premium properties across Syria.",
|
||||||
quickLinks: "Quick Links",
|
quickLinks: "Quick Links",
|
||||||
@ -1658,10 +1660,14 @@ const resources = {
|
|||||||
"calendar.mockTenant1": "Ahmed Mohammed",
|
"calendar.mockTenant1": "Ahmed Mohammed",
|
||||||
"calendar.mockTenant2": "Sara Ahmed",
|
"calendar.mockTenant2": "Sara Ahmed",
|
||||||
"calendar.mockTenant3": "Mohammed Ali",
|
"calendar.mockTenant3": "Mohammed Ali",
|
||||||
|
"loading":"Loading",
|
||||||
|
"neaebymosque":"Distance to nearest mosque (km)"
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
ar: {
|
ar: {
|
||||||
translation: {
|
translation: {
|
||||||
|
"loading":"جار التحميل",
|
||||||
|
"neaebymosque":"المسافة الى اقرب جامع",
|
||||||
/* Block*/
|
/* Block*/
|
||||||
"blocked.fillAllFields": "يرجى تعبئة جميع الحقول المطلوبة",
|
"blocked.fillAllFields": "يرجى تعبئة جميع الحقول المطلوبة",
|
||||||
"blocked.reportSent": "تم إرسال الرسالة بنجاح",
|
"blocked.reportSent": "تم إرسال الرسالة بنجاح",
|
||||||
@ -1776,6 +1782,7 @@ const resources = {
|
|||||||
"chooseRole.createAgentAccount": "إنشاء حساب وكيل",
|
"chooseRole.createAgentAccount": "إنشاء حساب وكيل",
|
||||||
"chooseRole.alreadyHaveAccount": "لديك حساب بالفعل؟",
|
"chooseRole.alreadyHaveAccount": "لديك حساب بالفعل؟",
|
||||||
|
|
||||||
|
Myseizedproperties:"عقاراتي المحجوزة",
|
||||||
/* ─── Role badges ─── */
|
/* ─── Role badges ─── */
|
||||||
visitor: "زائر",
|
visitor: "زائر",
|
||||||
owner: "مالك",
|
owner: "مالك",
|
||||||
@ -2032,6 +2039,8 @@ const resources = {
|
|||||||
|
|
||||||
/* ─── Bottom nav ─── */
|
/* ─── Bottom nav ─── */
|
||||||
payments: "المدفوعات",
|
payments: "المدفوعات",
|
||||||
|
Orders:"الطلبات",
|
||||||
|
Mybookings:"حجوزاتي",
|
||||||
|
|
||||||
/* ─── Footer ─── */
|
/* ─── Footer ─── */
|
||||||
footerDescription: "منصتك الموثوقة لإيجاد وإدراج العقارات الفاخرة في جميع أنحاء سوريا.",
|
footerDescription: "منصتك الموثوقة لإيجاد وإدراج العقارات الفاخرة في جميع أنحاء سوريا.",
|
||||||
|
|||||||
@ -1,8 +1,10 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { motion } from "framer-motion";
|
import { motion } from "framer-motion";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
export default function Loading() {
|
export default function Loading() {
|
||||||
|
const { t } = useTranslation();
|
||||||
return (
|
return (
|
||||||
<div className="min-h-screen flex items-center justify-center p-4" style={{ backgroundColor: "#08172f" }}>
|
<div className="min-h-screen flex items-center justify-center p-4" style={{ backgroundColor: "#08172f" }}>
|
||||||
<motion.div initial={{ opacity: 0, scale: 0.9 }} animate={{ opacity: 1, scale: 1.3 }} transition={{ duration: 0.4 }} className="text-center flex flex-col items-center justify-center gap-4">
|
<motion.div initial={{ opacity: 0, scale: 0.9 }} animate={{ opacity: 1, scale: 1.3 }} transition={{ duration: 0.4 }} className="text-center flex flex-col items-center justify-center gap-4">
|
||||||
@ -27,7 +29,9 @@ export default function Loading() {
|
|||||||
</div>
|
</div>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
|
|
||||||
<p className="text-amber-400 text-sm font-bold tracking-wide animate-pulse">... جاري التحميل</p>
|
<p className="text-amber-400 text-sm font-bold tracking-wide animate-pulse" suppressHydrationWarning>
|
||||||
|
... {t("loading")}
|
||||||
|
</p>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,14 +0,0 @@
|
|||||||
'use client';
|
|
||||||
|
|
||||||
import { motion } from 'framer-motion';
|
|
||||||
|
|
||||||
export default function Loading() {
|
|
||||||
return (
|
|
||||||
<div className="min-h-screen bg-gradient-to-br from-gray-950 via-gray-900 to-gray-950 flex items-center justify-center">
|
|
||||||
<motion.div initial={{ opacity: 0 }} animate={{ opacity: 1 }} className="text-center">
|
|
||||||
<div className="w-14 h-14 border-4 border-amber-500 border-t-transparent rounded-full animate-spin mx-auto mb-4" />
|
|
||||||
<p className="text-gray-400 text-lg">جاري التحميل...</p>
|
|
||||||
</motion.div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -141,6 +141,7 @@ export default function AddPropertyPage() {
|
|||||||
nearbyUniversity: "",
|
nearbyUniversity: "",
|
||||||
nearbyPark: "",
|
nearbyPark: "",
|
||||||
nearbyMall: "",
|
nearbyMall: "",
|
||||||
|
neaebymosque: "",
|
||||||
|
|
||||||
roomAreaType: "Private room",
|
roomAreaType: "Private room",
|
||||||
roomPeopleAllowed: "",
|
roomPeopleAllowed: "",
|
||||||
@ -693,6 +694,7 @@ export default function AddPropertyPage() {
|
|||||||
university: formData.nearbyUniversity || "",
|
university: formData.nearbyUniversity || "",
|
||||||
park: formData.nearbyPark || "",
|
park: formData.nearbyPark || "",
|
||||||
mall: formData.nearbyMall || "",
|
mall: formData.nearbyMall || "",
|
||||||
|
mosque: formData.neaebymosque || "",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -747,11 +749,9 @@ export default function AddPropertyPage() {
|
|||||||
try {
|
try {
|
||||||
if (purpose === "sale") {
|
if (purpose === "sale") {
|
||||||
const payload = {
|
const payload = {
|
||||||
|
propInfo,
|
||||||
propInfo,
|
price: parseFloat(formData.salePrice),
|
||||||
price: parseFloat(formData.salePrice),
|
deposit: parseFloat(formData.deposit) || 0,
|
||||||
deposit: parseFloat(formData.deposit) || 0,
|
|
||||||
|
|
||||||
};
|
};
|
||||||
console.log("ff", payload);
|
console.log("ff", payload);
|
||||||
const res = await addSaleProperty(payload);
|
const res = await addSaleProperty(payload);
|
||||||
@ -862,7 +862,7 @@ export default function AddPropertyPage() {
|
|||||||
type="button"
|
type="button"
|
||||||
onClick={() => setFormData({ ...formData, propertyType: type.id })}
|
onClick={() => setFormData({ ...formData, propertyType: type.id })}
|
||||||
className={`p-4 border rounded-xl flex flex-col items-center gap-2 transition-all ${
|
className={`p-4 border rounded-xl flex flex-col items-center gap-2 transition-all ${
|
||||||
formData.propertyType === type.id ? "border-amber-500 bg-amber-50 text-amber-700" : "border-gray-200 hover:border-amber-200 hover:bg-amber-50/50"
|
formData.propertyType === type.id ? "border-amber-500 bg-[#1E293B] text-amber-700" : "border-gray-200 hover:border-amber-200 hover:bg-amber-50/50"
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<Icon className="w-6 h-6" />
|
<Icon className="w-6 h-6" />
|
||||||
@ -895,7 +895,7 @@ export default function AddPropertyPage() {
|
|||||||
<select
|
<select
|
||||||
value={formData.documentType}
|
value={formData.documentType}
|
||||||
onChange={(e) => setFormData({ ...formData, documentType: e.target.value })}
|
onChange={(e) => setFormData({ ...formData, documentType: e.target.value })}
|
||||||
className="w-full px-4 py-3 border border-gray-300 rounded-xl focus:outline-none focus:ring-2 focus:ring-amber-500"
|
className="w-full px-4 bg-[#1E293B] py-3 border border-gray-300 rounded-xl focus:outline-none focus:ring-2 focus:ring-amber-500"
|
||||||
>
|
>
|
||||||
{DocumentTypeList.map((type) => (
|
{DocumentTypeList.map((type) => (
|
||||||
<option key={type} value={type}>
|
<option key={type} value={type}>
|
||||||
@ -1037,19 +1037,19 @@ export default function AddPropertyPage() {
|
|||||||
const Icon = service.icon;
|
const Icon = service.icon;
|
||||||
const isSelected = formData.services[service.id];
|
const isSelected = formData.services[service.id];
|
||||||
return (
|
return (
|
||||||
<div key={service.id} className={`border rounded-xl transition-all ${isSelected ? "border-amber-500 bg-amber-50" : "border-gray-200"}`}>
|
<div key={service.id} className={`border rounded-xl transition-all ${isSelected ? "border-amber-500 bg-[#1E293B]" : "border-gray-200"}`}>
|
||||||
<label className="flex items-center gap-3 p-3 cursor-pointer">
|
<label className="flex items-center gap-3 p-3 cursor-pointer">
|
||||||
<input type="checkbox" checked={isSelected} onChange={() => toggleService(service.id)} className="w-4 h-4 text-amber-500 rounded" />
|
<input type="checkbox" checked={isSelected} onChange={() => toggleService(service.id)} className="w-4 h-4 bg-[#1E293B] text-amber-500 rounded" />
|
||||||
<Icon className={`w-5 h-5 ${isSelected ? "text-amber-600" : "text-gray-400"}`} />
|
<Icon className={`w-5 h-5 ${isSelected ? "text-amber-600" : "text-gray-400"}`} />
|
||||||
<span className={`text-sm font-medium ${isSelected ? "text-amber-700" : "text-gray-600"}`}>{service.label}</span>
|
<span className={`text-sm font-medium ${isSelected ? "text-amber-700" : "text-gray-600"}`}>{service.label}</span>
|
||||||
</label>
|
</label>
|
||||||
{isSelected && (
|
{isSelected && (
|
||||||
<div className="px-3 pb-3">
|
<div className="px-3 pb-3 bg-[#1E293B]">
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
value={formData.serviceDetails[service.id] || ""}
|
value={formData.serviceDetails[service.id] || ""}
|
||||||
onChange={(e) => updateServiceDetail(service.id, e.target.value)}
|
onChange={(e) => updateServiceDetail(service.id, e.target.value)}
|
||||||
className="w-full px-3 py-2 border border-gray-200 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-amber-500"
|
className="w-full px-3 py-2 border bg-[#1E293B] border-gray-200 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-amber-500"
|
||||||
placeholder={t("addProperty.serviceDetailPlaceholder")}
|
placeholder={t("addProperty.serviceDetailPlaceholder")}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@ -1060,7 +1060,7 @@ export default function AddPropertyPage() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="bg-white rounded-xl p-6 border border-gray-200 mt-6">
|
<div className="bg-[#1E293B] rounded-xl p-6 border border-gray-200 mt-6">
|
||||||
<h3 className="text-lg font-bold text-gray-800 mb-4 flex items-center gap-2">
|
<h3 className="text-lg font-bold text-gray-800 mb-4 flex items-center gap-2">
|
||||||
<MapPin className="w-5 h-5 text-amber-600" />
|
<MapPin className="w-5 h-5 text-amber-600" />
|
||||||
{t("addProperty.nearbyServicesTitle")}
|
{t("addProperty.nearbyServicesTitle")}
|
||||||
@ -1090,6 +1090,19 @@ export default function AddPropertyPage() {
|
|||||||
placeholder={t("addProperty.nearbyPlaceholder")}
|
placeholder={t("addProperty.nearbyPlaceholder")}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
<label className="block text-sm font-medium text-gray-700 mb-2">{t("neaebymosque")}</label>
|
||||||
|
<input
|
||||||
|
type="number"
|
||||||
|
min="0"
|
||||||
|
step="0.1"
|
||||||
|
required
|
||||||
|
value={formData.neaebymosque}
|
||||||
|
onChange={(e) => setFormData({ ...formData, neaebymosque: e.target.value })}
|
||||||
|
className="w-full px-4 py-3 border border-gray-300 rounded-xl focus:outline-none focus:ring-2 focus:ring-amber-500"
|
||||||
|
placeholder={t("addProperty.nearbyPlaceholder")}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-sm font-medium text-gray-700 mb-2">{t("addProperty.nearbyRestaurantLabel")}</label>
|
<label className="block text-sm font-medium text-gray-700 mb-2">{t("addProperty.nearbyRestaurantLabel")}</label>
|
||||||
<input
|
<input
|
||||||
@ -1151,7 +1164,7 @@ export default function AddPropertyPage() {
|
|||||||
<label
|
<label
|
||||||
key={term.id}
|
key={term.id}
|
||||||
className={`flex items-center gap-2 p-3 border rounded-xl cursor-pointer transition-all ${
|
className={`flex items-center gap-2 p-3 border rounded-xl cursor-pointer transition-all ${
|
||||||
formData.terms[term.id] ? "border-amber-500 bg-amber-50" : "border-gray-200 hover:border-amber-200 hover:bg-amber-50/50"
|
formData.terms[term.id] ? "border-amber-500 bg-[#1E293B]" : "border-gray-200 hover:border-amber-200 hover:bg-amber-50/50"
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<input type="checkbox" checked={formData.terms[term.id]} onChange={() => toggleTerm(term.id)} className="hidden" />
|
<input type="checkbox" checked={formData.terms[term.id]} onChange={() => toggleTerm(term.id)} className="hidden" />
|
||||||
@ -1208,7 +1221,7 @@ export default function AddPropertyPage() {
|
|||||||
{step === 3 && purpose === "sale" && (
|
{step === 3 && purpose === "sale" && (
|
||||||
<motion.div variants={fadeInUp} className="space-y-8">
|
<motion.div variants={fadeInUp} className="space-y-8">
|
||||||
<div className="text-center mb-6">
|
<div className="text-center mb-6">
|
||||||
<div className="w-20 h-20 bg-amber-100 rounded-2xl flex items-center justify-center mx-auto mb-4">
|
<div className="w-20 h-20 bg-amber-500 rounded-2xl flex items-center justify-center mx-auto mb-4">
|
||||||
<DollarSign className="w-10 h-10 text-amber-600" />
|
<DollarSign className="w-10 h-10 text-amber-600" />
|
||||||
</div>
|
</div>
|
||||||
<h2 className="text-2xl font-bold text-gray-900 mb-2">{t("addProperty.salePriceTitle")}</h2>
|
<h2 className="text-2xl font-bold text-gray-900 mb-2">{t("addProperty.salePriceTitle")}</h2>
|
||||||
@ -1234,7 +1247,7 @@ export default function AddPropertyPage() {
|
|||||||
onKeyDown={(e) => {
|
onKeyDown={(e) => {
|
||||||
if (["-", "e", "E", "+"].includes(e.key)) e.preventDefault();
|
if (["-", "e", "E", "+"].includes(e.key)) e.preventDefault();
|
||||||
}}
|
}}
|
||||||
className={`w-full pr-12 pl-4 py-3 border rounded-xl focus:outline-none focus:ring-2 focus:ring-amber-500 ${errors.salePrice ? "border-red-500" : "border-gray-300"}`}
|
className={`w-full pr-12 pl-4 py-3 border rounded-xl focus:outline-none focus:ring-2 focus:ring-amber-500 ${errors.salePrice ? "border-red-500" : "border-gray-300"}`}
|
||||||
placeholder={t("addProperty.salePricePlaceholder")}
|
placeholder={t("addProperty.salePricePlaceholder")}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@ -1248,7 +1261,7 @@ export default function AddPropertyPage() {
|
|||||||
<select
|
<select
|
||||||
value={selectedCurrencyId}
|
value={selectedCurrencyId}
|
||||||
onChange={(e) => setSelectedCurrencyId(parseInt(e.target.value))}
|
onChange={(e) => setSelectedCurrencyId(parseInt(e.target.value))}
|
||||||
className="w-full px-4 py-3 border border-gray-300 rounded-xl focus:outline-none focus:ring-2 focus:ring-amber-500"
|
className="w-full px-4 py-3 border border-gray-300 bg-[#1E293B] rounded-xl focus:outline-none focus:ring-2 focus:ring-amber-500"
|
||||||
>
|
>
|
||||||
<option value={Currency.USD}>{t("addProperty.usdOption")}</option>
|
<option value={Currency.USD}>{t("addProperty.usdOption")}</option>
|
||||||
<option value={Currency.SYP}>{t("addProperty.sypOption")}</option>
|
<option value={Currency.SYP}>{t("addProperty.sypOption")}</option>
|
||||||
@ -1280,7 +1293,7 @@ export default function AddPropertyPage() {
|
|||||||
type="button"
|
type="button"
|
||||||
onClick={() => setFormData({ ...formData, offerType: type.id })}
|
onClick={() => setFormData({ ...formData, offerType: type.id })}
|
||||||
className={`p-4 border rounded-xl flex flex-col items-center gap-2 transition-all ${
|
className={`p-4 border rounded-xl flex flex-col items-center gap-2 transition-all ${
|
||||||
formData.offerType === type.id ? "border-amber-500 bg-amber-50 text-amber-700" : "border-gray-200 hover:border-amber-200 hover:bg-amber-50/50"
|
formData.offerType === type.id ? "border-amber-500 bg-[#1E293B] text-amber-700" : "border-gray-200 hover:border-amber-200 hover:bg-amber-50/50"
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<Icon className="w-6 h-6" />
|
<Icon className="w-6 h-6" />
|
||||||
@ -1290,7 +1303,7 @@ export default function AddPropertyPage() {
|
|||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{/* كمسيون */}
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-sm font-medium text-gray-700 mb-2">
|
<label className="block text-sm font-medium text-gray-700 mb-2">
|
||||||
{t("addProperty.currencyLabel")} <span className="text-red-500">*</span>
|
{t("addProperty.currencyLabel")} <span className="text-red-500">*</span>
|
||||||
@ -1298,7 +1311,7 @@ export default function AddPropertyPage() {
|
|||||||
<select
|
<select
|
||||||
value={selectedCurrencyId}
|
value={selectedCurrencyId}
|
||||||
onChange={(e) => setSelectedCurrencyId(parseInt(e.target.value))}
|
onChange={(e) => setSelectedCurrencyId(parseInt(e.target.value))}
|
||||||
className="w-full px-4 py-3 border border-gray-300 rounded-xl focus:outline-none focus:ring-2 focus:ring-amber-500"
|
className="w-full px-4 py-3 border bg-[#1E293B] border-gray-300 rounded-xl focus:outline-none focus:ring-2 focus:ring-amber-500"
|
||||||
>
|
>
|
||||||
<option value={Currency.USD}>{t("addProperty.usdOption")}</option>
|
<option value={Currency.USD}>{t("addProperty.usdOption")}</option>
|
||||||
<option value={Currency.SYP}>{t("addProperty.sypOption")}</option>
|
<option value={Currency.SYP}>{t("addProperty.sypOption")}</option>
|
||||||
@ -1506,8 +1519,8 @@ export default function AddPropertyPage() {
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
{step === 4 && (
|
{step === 4 && (
|
||||||
<motion.div variants={fadeInUp} className="space-y-8">
|
<motion.div variants={fadeInUp} className="space-y-8 ">
|
||||||
<div className="text-center mb-6">
|
<div className="text-center mb-6 ">
|
||||||
<div className="w-20 h-20 bg-amber-100 rounded-2xl flex items-center justify-center mx-auto mb-4">
|
<div className="w-20 h-20 bg-amber-100 rounded-2xl flex items-center justify-center mx-auto mb-4">
|
||||||
<MapPin className="w-10 h-10 text-amber-600" />
|
<MapPin className="w-10 h-10 text-amber-600" />
|
||||||
</div>
|
</div>
|
||||||
@ -1515,7 +1528,7 @@ export default function AddPropertyPage() {
|
|||||||
<p className="text-gray-600">{t("addProperty.locationAndImagesSubtitle")}</p>
|
<p className="text-gray-600">{t("addProperty.locationAndImagesSubtitle")}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="rounded-3xl border border-amber-100 bg-linear-to-br from-amber-50 via-white to-orange-50 p-4 sm:p-5 md:p-6 shadow-sm">
|
<div className="rounded-3xl border border-amber-100 p-4 sm:p-5 md:p-6 shadow-sm">
|
||||||
<div className="flex flex-col gap-3 md:flex-row md:items-start md:justify-between mb-5">
|
<div className="flex flex-col gap-3 md:flex-row md:items-start md:justify-between mb-5">
|
||||||
<div>
|
<div>
|
||||||
<div className="flex items-center gap-2 text-amber-700 font-semibold mb-1">
|
<div className="flex items-center gap-2 text-amber-700 font-semibold mb-1">
|
||||||
@ -1568,7 +1581,7 @@ export default function AddPropertyPage() {
|
|||||||
{t("addProperty.searchButton")}
|
{t("addProperty.searchButton")}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div className="mt-3 flex items-start gap-2 text-sm text-amber-700">
|
<div className="mt-3 flex items-start gap-2 text-sm text-amber-700">
|
||||||
<Info className="w-4 h-4 mt-0.5 shrink-0" />
|
<Info className="w-4 h-4 mt-0.5 shrink-0" />
|
||||||
<span>{t("addProperty.clickMapHint")}</span>
|
<span>{t("addProperty.clickMapHint")}</span>
|
||||||
</div>
|
</div>
|
||||||
@ -1589,7 +1602,7 @@ export default function AddPropertyPage() {
|
|||||||
{t("addProperty.confirmLocation")}
|
{t("addProperty.confirmLocation")}
|
||||||
</button>
|
</button>
|
||||||
) : (
|
) : (
|
||||||
<div className="rounded-2xl border border-amber-100 bg-amber-50 px-4 py-3 text-sm text-amber-800 flex items-start gap-2">
|
<div className="rounded-2xl border border-amber-100 bg-[#1E293B] px-4 py-3 text-sm text-amber-800 flex items-start gap-2">
|
||||||
<Info className="w-4 h-4 mt-0.5 shrink-0" />
|
<Info className="w-4 h-4 mt-0.5 shrink-0" />
|
||||||
<span>{t("addProperty.clickMapHint")}</span>
|
<span>{t("addProperty.clickMapHint")}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,14 +0,0 @@
|
|||||||
'use client';
|
|
||||||
|
|
||||||
import { motion } from 'framer-motion';
|
|
||||||
|
|
||||||
export default function Loading() {
|
|
||||||
return (
|
|
||||||
<div className="min-h-screen bg-gradient-to-br from-gray-950 via-gray-900 to-gray-950 flex items-center justify-center">
|
|
||||||
<motion.div initial={{ opacity: 0 }} animate={{ opacity: 1 }} className="text-center">
|
|
||||||
<div className="w-14 h-14 border-4 border-amber-500 border-t-transparent rounded-full animate-spin mx-auto mb-4" />
|
|
||||||
<p className="text-gray-400 text-lg">جاري التحميل...</p>
|
|
||||||
</motion.div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
@ -54,6 +54,7 @@ import {
|
|||||||
Dog,
|
Dog,
|
||||||
CassetteTape,
|
CassetteTape,
|
||||||
Info,
|
Info,
|
||||||
|
Theater,
|
||||||
} from "lucide-react";
|
} from "lucide-react";
|
||||||
import { getRentProperty, getSaleProperty, getSalePropertyById, bookReservation, getAvailableDateRanges, getOwnerContactInformation, getMyRentListings, getMySaleListings } from "../../utils/api";
|
import { getRentProperty, getSaleProperty, getSalePropertyById, bookReservation, getAvailableDateRanges, getOwnerContactInformation, getMyRentListings, getMySaleListings } from "../../utils/api";
|
||||||
import AuthService from "../../services/AuthService";
|
import AuthService from "../../services/AuthService";
|
||||||
@ -584,7 +585,7 @@ export default function PropertyDetailsPage() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Price */}
|
{/* Price */}
|
||||||
<div className="bg-amber-50 rounded-xl p-3 mb-4">
|
<div className="bg-[#1E293B] rounded-xl p-3 mb-4">
|
||||||
{property.isRent ? (
|
{property.isRent ? (
|
||||||
<div className="flex flex-wrap gap-6 items-end">
|
<div className="flex flex-wrap gap-6 items-end">
|
||||||
{property.priceDisplay.monthly > 0 && (
|
{property.priceDisplay.monthly > 0 && (
|
||||||
@ -856,12 +857,13 @@ export default function PropertyDetailsPage() {
|
|||||||
return (
|
return (
|
||||||
<div key={key} className="bg-gray-50 rounded-lg p-2 flex items-center gap-1.5">
|
<div key={key} className="bg-gray-50 rounded-lg p-2 flex items-center gap-1.5">
|
||||||
{key === "School" && <School className="w-3.5 h-3.5 text-amber-500 flex-shrink-0" />}
|
{key === "School" && <School className="w-3.5 h-3.5 text-amber-500 flex-shrink-0" />}
|
||||||
|
{key === "Mosque" && <Theater className="w-3.5 h-3.5 text-amber-500 flex-shrink-0" />}
|
||||||
{key === "Hospital" && <Hospital className="w-3.5 h-3.5 text-amber-500 flex-shrink-0" />}
|
{key === "Hospital" && <Hospital className="w-3.5 h-3.5 text-amber-500 flex-shrink-0" />}
|
||||||
{key === "Restaurant" && <Store className="w-3.5 h-3.5 text-amber-500 flex-shrink-0" />}
|
{key === "Restaurant" && <Store className="w-3.5 h-3.5 text-amber-500 flex-shrink-0" />}
|
||||||
{key === "University" && <GraduationCap className="w-3.5 h-3.5 text-amber-500 flex-shrink-0" />}
|
{key === "University" && <GraduationCap className="w-3.5 h-3.5 text-amber-500 flex-shrink-0" />}
|
||||||
{key === "Park" && <TreePine className="w-3.5 h-3.5 text-amber-500 flex-shrink-0" />}
|
{key === "Park" && <TreePine className="w-3.5 h-3.5 text-amber-500 flex-shrink-0" />}
|
||||||
{key === "Mall" && <Building className="w-3.5 h-3.5 text-amber-500 flex-shrink-0" />}
|
{key === "Mall" && <Building className="w-3.5 h-3.5 text-amber-500 flex-shrink-0" />}
|
||||||
{!["School", "Hospital", "Restaurant", "University", "Park", "Mall"].includes(key) && <MapPin className="w-3.5 h-3.5 text-amber-500 flex-shrink-0" />}
|
{!["School", "Hospital", "Restaurant", "University", "Park", "Mall","Mosque"].includes(key) && <MapPin className="w-3.5 h-3.5 text-amber-500 flex-shrink-0" />}
|
||||||
<div>
|
<div>
|
||||||
<div className="text-xs font-medium text-gray-900">{t(proxKey(key))}</div>
|
<div className="text-xs font-medium text-gray-900">{t(proxKey(key))}</div>
|
||||||
<div className="text-[10px] text-gray-500">
|
<div className="text-[10px] text-gray-500">
|
||||||
@ -952,7 +954,7 @@ export default function PropertyDetailsPage() {
|
|||||||
<div className="grid grid-cols-2 gap-2 mb-3">
|
<div className="grid grid-cols-2 gap-2 mb-3">
|
||||||
<button
|
<button
|
||||||
onClick={() => setPricingMode("daily")}
|
onClick={() => setPricingMode("daily")}
|
||||||
className={`p-2.5 rounded-xl text-center border-2 transition-all ${effectivePricingMode === "daily" ? "border-amber-500 bg-amber-50" : "border-gray-200 hover:border-gray-300"}`}
|
className={`p-2.5 rounded-xl text-center border-2 transition-all ${effectivePricingMode === "daily" ? "border-amber-500 bg-[#1E293B]" : "border-gray-200 hover:border-gray-300"}`}
|
||||||
>
|
>
|
||||||
<div className="text-xs font-bold text-gray-900">{t("dailyRentLabel")}</div>
|
<div className="text-xs font-bold text-gray-900">{t("dailyRentLabel")}</div>
|
||||||
<div className="text-sm font-bold text-amber-600">
|
<div className="text-sm font-bold text-amber-600">
|
||||||
@ -961,7 +963,7 @@ export default function PropertyDetailsPage() {
|
|||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
onClick={() => setPricingMode("monthly")}
|
onClick={() => setPricingMode("monthly")}
|
||||||
className={`p-2.5 rounded-xl text-center border-2 transition-all ${effectivePricingMode === "monthly" ? "border-amber-500 bg-amber-50" : "border-gray-200 hover:border-gray-300"}`}
|
className={`p-2.5 rounded-xl text-center border-2 transition-all ${effectivePricingMode === "monthly" ? "border-amber-500 bg-[#1E293B]" : "border-gray-200 hover:border-gray-300"}`}
|
||||||
>
|
>
|
||||||
<div className="text-xs font-bold text-gray-900">{t("monthlyRentLabel")}</div>
|
<div className="text-xs font-bold text-gray-900">{t("monthlyRentLabel")}</div>
|
||||||
<div className="text-sm font-bold text-amber-600">
|
<div className="text-sm font-bold text-amber-600">
|
||||||
@ -997,7 +999,7 @@ export default function PropertyDetailsPage() {
|
|||||||
<span className="text-gray-500">{t("endDateLabel")}</span>
|
<span className="text-gray-500">{t("endDateLabel")}</span>
|
||||||
<span className="font-medium text-gray-900">{selectedEnd}</span>
|
<span className="font-medium text-gray-900">{selectedEnd}</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="border-t border-gray-200 my-1" />
|
<div className="border-t border-gray-200 my-1 " />
|
||||||
<div className="flex justify-between text-xs">
|
<div className="flex justify-between text-xs">
|
||||||
<span className="text-gray-500">{effectivePricingMode === "daily" ? t("numberOfDays") : t("numberOfMonths")}</span>
|
<span className="text-gray-500">{effectivePricingMode === "daily" ? t("numberOfDays") : t("numberOfMonths")}</span>
|
||||||
<span className="font-medium text-gray-900">
|
<span className="font-medium text-gray-900">
|
||||||
@ -1053,7 +1055,7 @@ export default function PropertyDetailsPage() {
|
|||||||
{/* Login Dialog */}
|
{/* Login Dialog */}
|
||||||
{showLoginDialog && (
|
{showLoginDialog && (
|
||||||
<div className="fixed inset-0 bg-black/50 flex items-center justify-center z-50" onClick={() => setShowLoginDialog(false)}>
|
<div className="fixed inset-0 bg-black/50 flex items-center justify-center z-50" onClick={() => setShowLoginDialog(false)}>
|
||||||
<div className="bg-white rounded-2xl p-6 max-w-sm text-center mx-4" onClick={(e) => e.stopPropagation()}>
|
<div className="bg-[#1E293B] rounded-2xl p-6 max-w-sm text-center mx-4" onClick={(e) => e.stopPropagation()}>
|
||||||
<div className="w-16 h-16 bg-amber-100 rounded-full flex items-center justify-center mx-auto mb-4">
|
<div className="w-16 h-16 bg-amber-100 rounded-full flex items-center justify-center mx-auto mb-4">
|
||||||
<LogIn className="w-8 h-8 text-amber-600" />
|
<LogIn className="w-8 h-8 text-amber-600" />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -61,7 +61,7 @@ export default function TenantRegisterPage() {
|
|||||||
email: formData.email,
|
email: formData.email,
|
||||||
phoneNumber: formData.phone,
|
phoneNumber: formData.phone,
|
||||||
whatsAppNumber: formData.whatsapp,
|
whatsAppNumber: formData.whatsapp,
|
||||||
phone: formData.phone2,
|
phone: formData.phone2 || "" ,
|
||||||
nationalNumber: formData.nationalNumber,
|
nationalNumber: formData.nationalNumber,
|
||||||
password: formData.password,
|
password: formData.password,
|
||||||
customerType: formData.customerType,
|
customerType: formData.customerType,
|
||||||
|
|||||||
@ -17,12 +17,7 @@ export const validateStep1 = (formData, setErrors, t) => {
|
|||||||
newErrors.email = t("register.emailInvalid");
|
newErrors.email = t("register.emailInvalid");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!formData.phone?.trim()) {
|
|
||||||
newErrors.phone = t("register.phoneRequired");
|
|
||||||
} else if (!validatePhone(formData.phone)) {
|
|
||||||
newErrors.phone = `${t("register.phoneInvalid")} (${t("register.phoneMustStartWith")} 09/05)`;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!formData.whatsapp?.trim()) {
|
if (!formData.whatsapp?.trim()) {
|
||||||
newErrors.whatsapp = t("register.whatsappRequired");
|
newErrors.whatsapp = t("register.whatsappRequired");
|
||||||
} else if (!validatePhone(formData.whatsapp)) {
|
} else if (!validatePhone(formData.whatsapp)) {
|
||||||
|
|||||||
Reference in New Issue
Block a user