Added translation to payments
All checks were successful
Build frontend / build (push) Successful in 1m43s

This commit is contained in:
Rahaf
2026-07-02 10:38:55 +03:00
parent dab5b62fb7
commit c7698741c7
3 changed files with 68 additions and 49 deletions

View File

@ -30,47 +30,27 @@ import { payDeposit, getMyTransaction } from '@/app/utils/api';
const STATUS_MAP = ['pending', 'ownerConfirmed', 'depositPaid', 'depositConfirmed', 'completed', 'cancelled'];
const STATUS_CONFIG = {
pending: { label: 'قيد الانتظار', color: 'bg-yellow-100 text-yellow-800 border-yellow-300', icon: Clock },
ownerConfirmed: { label: 'مؤكد من المالك', color: 'bg-blue-100 text-blue-800 border-blue-300', icon: ShieldCheck },
depositPaid: { label: 'تم دفع السلفة', color: 'bg-orange-100 text-orange-800 border-orange-300', icon: Wallet },
depositConfirmed: { label: 'تم تأكيد الدفع', color: 'bg-green-100 text-green-800 border-green-300', icon: Check },
completed: { label: 'منتهي', color: 'bg-teal-100 text-teal-800 border-teal-300', icon: Check },
cancelled: { label: 'ملغي', color: 'bg-red-100 text-red-800 border-red-300', icon: X },
};
function getStatusConfig(t) {
return {
pending: { label: t('bookingStatus.pending'), color: 'bg-yellow-100 text-yellow-800 border-yellow-300', icon: Clock },
ownerConfirmed: { label: t('bookingStatus.ownerConfirmed'), color: 'bg-blue-100 text-blue-800 border-blue-300', icon: ShieldCheck },
depositPaid: { label: t('bookingStatus.depositPaid'), color: 'bg-orange-100 text-orange-800 border-orange-300', icon: Wallet },
depositConfirmed: { label: t('bookingStatus.depositConfirmed'), color: 'bg-green-100 text-green-800 border-green-300', icon: Check },
completed: { label: t('bookingStatus.completed'), color: 'bg-teal-100 text-teal-800 border-teal-300', icon: Check },
cancelled: { label: t('bookingStatus.cancelled'), color: 'bg-red-100 text-red-800 border-red-300', icon: X },
};
}
const PAYMENT_METHODS = [
{
id: 'cash',
label: 'الدفع النقدي',
desc: 'ادفع الآن عبر شام كاش مع تأكيد تلقائي للحجز',
icon: Banknote,
active: true,
},
{
id: 'office',
label: 'نقداً',
desc: 'ادفع في مكتب المنصة. يتم التأكيد لاحقاً',
icon: Building,
active: true,
},
{
id: 'transfer',
label: 'تحويل داخلي',
desc: 'حول من حساب داخلي ثم أرسل المرجع',
icon: ArrowLeftRight,
active: false,
},
{
id: 'electronic',
label: 'دفع إلكتروني',
desc: 'سيتم تفعيل الدفع الإلكتروني والتحويل لاحقاً',
icon: CreditCard,
active: false,
}
];
function getPaymentMethods(t) {
return [
{ id: 'cash', label: t('payments.method.cash'), desc: t('payments.method.cashDesc'), icon: Banknote, active: true },
{ id: 'office', label: t('payments.method.office'), desc: t('payments.method.officeDesc'), icon: Building, active: true },
{ id: 'transfer', label: t('payments.method.transfer'), desc: t('payments.method.transferDesc'), icon: ArrowLeftRight, active: false },
{ id: 'electronic', label: t('payments.method.electronic'), desc: t('payments.method.electronicDesc'), icon: CreditCard, active: false },
];
}
function formatCurrency(v, sign = 'ل.س') {
function formatCurrency(v, sign = '') {
return `${sign} ${Number(v ?? 0).toLocaleString()}`;
}
@ -82,7 +62,7 @@ function formatDate(date) {
}
export default function PaymentsPage() {
const { t } = useTranslation();
const { t, i18n } = useTranslation();
const [reservations, setReservations] = useState([]);
const [loading, setLoading] = useState(true);
const [payingId, setPayingId] = useState(null);
@ -109,10 +89,10 @@ export default function PaymentsPage() {
endDate: reservation.endDate,
totalPrice: reservation.totalPrice ?? transaction.amount ?? 0,
depositAmount: transaction.amount ?? reservation.totalPrice ?? 0,
currencySign: currency.sign || 'ل.س',
currencySign: currency.sign || t('currency.syp'),
currencyName: currency.name || '',
currencyRate: currency.rate,
propertyName: propertyInfo.name || propertyInfo.address || reservation.propertyName || `عقار #${reservation.id || ''}`,
propertyName: propertyInfo.name || propertyInfo.address || reservation.propertyName || `${t('payments.propertyLabel')} #${reservation.id || ''}`,
propertyAddress: propertyInfo.address || reservation.propertyAddress || '',
propertyCity: propertyInfo.city || reservation.city || '',
_deposit: deposit,
@ -127,7 +107,7 @@ export default function PaymentsPage() {
} finally {
setLoading(false);
}
}, []);
}, [t]);
useEffect(() => {
if (AuthService.isGuest()) {
@ -156,7 +136,7 @@ export default function PaymentsPage() {
if (loading) {
return (
<div className="min-h-screen bg-gray-50 flex items-center justify-center" dir="rtl">
<div className="min-h-screen bg-gray-50 flex items-center justify-center" dir={i18n.dir()}>
<Loader2 className="w-12 h-12 text-amber-500 animate-spin" />
</div>
);
@ -164,7 +144,7 @@ export default function PaymentsPage() {
if (isGuest) {
return (
<div className="min-h-screen bg-gradient-to-b from-amber-50/50 to-white flex items-center justify-center p-4" dir="rtl">
<div className="min-h-screen bg-gradient-to-b from-amber-50/50 to-white flex items-center justify-center p-4" dir={i18n.dir()}>
<motion.div
initial={{ opacity: 0, scale: 0.95 }}
animate={{ opacity: 1, scale: 1 }}
@ -193,7 +173,7 @@ export default function PaymentsPage() {
const others = reservations.filter((r) => !canPay(r.status));
return (
<div className="min-h-screen bg-gray-50 py-8" dir="rtl">
<div className="min-h-screen bg-gray-50 py-8" dir={i18n.dir()}>
<Toaster position="top-center" reverseOrder={false} />
<div className="container mx-auto px-4 max-w-4xl">
<motion.div
@ -232,7 +212,7 @@ export default function PaymentsPage() {
</h2>
{others.map((r, i) => {
const statusKey = STATUS_MAP[r.status] || 'pending';
const cfg = STATUS_CONFIG[statusKey];
const cfg = getStatusConfig(t)[statusKey];
const Icon = cfg.icon;
const amount = r.depositAmount || r.totalPrice || 0;
@ -352,7 +332,7 @@ export default function PaymentsPage() {
<div className="px-6 py-5 border-b border-gray-100">
<p className="text-sm font-bold text-gray-700 mb-3">{t('payments.paymentMethodLabel')}</p>
<div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
{PAYMENT_METHODS.map((method) => {
{getPaymentMethods(t).map((method) => {
const isSelected = selectedPayment === method.id;
const Icon = method.icon;
return (