From 430e0b3b116970a711c0af0971c8c8a87df06b5f Mon Sep 17 00:00:00 2001 From: hamed <15238-genius.ha@users.noreply.drupalcode.org> Date: Tue, 18 Nov 2025 21:37:05 +0330 Subject: [PATCH] refactor: enhance payment handling by adding frontend_address to payment payload and implement PaymentDetailsPage component --- app/payment/[uuid]/page.js | 231 +++++++++++++++++++++++++ components/appointment/paying/index.js | 3 +- services/response.js | 1 + 3 files changed, 234 insertions(+), 1 deletion(-) create mode 100644 app/payment/[uuid]/page.js diff --git a/app/payment/[uuid]/page.js b/app/payment/[uuid]/page.js new file mode 100644 index 0000000..a98bbd2 --- /dev/null +++ b/app/payment/[uuid]/page.js @@ -0,0 +1,231 @@ +"use client"; + +import { useEffect, useState } from "react"; +import { useParams, useRouter } from "next/navigation"; +import { request } from "@/services/response"; +import Cookies from "js-cookie"; +import Layout from "@/components/layout"; + +export default function PaymentDetailsPage() { + const params = useParams(); + const router = useRouter(); + const [payment, setPayment] = useState(null); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(null); + + useEffect(() => { + // بررسی لاگین بودن کاربر + const userInfo = Cookies.get("userInfo"); + if (!userInfo) { + router.push("/login"); + return; + } + + const fetchPaymentDetails = async () => { + try { + setLoading(true); + const response = await request.getPayment(params.uuid); + setPayment(response); + } catch (err) { + setError("خطا در دریافت اطلاعات پرداخت"); + console.error("Payment fetch error:", err); + } finally { + setLoading(false); + } + }; + + if (params.uuid) { + fetchPaymentDetails(); + } + }, [params.uuid, router]); + + const getStatusLabel = (status) => { + const statusMap = { + pending: "در انتظار پرداخت", + completed: "پرداخت موفق", + failed: "پرداخت ناموفق", + canceled: "لغو شده", + }; + return statusMap[status] || status; + }; + + const getStatusColor = (status) => { + const colorMap = { + pending: "text-yellow-600 bg-yellow-50", + completed: "text-green-600 bg-green-50", + failed: "text-red-600 bg-red-50", + canceled: "text-gray-600 bg-gray-50", + }; + return colorMap[status] || "text-gray-600 bg-gray-50"; + }; + + const getPaymentMethodLabel = (method) => { + const methodMap = { + mellat: "بانک ملت", + saman: "سامان کیش", + }; + return methodMap[method] || method; + }; + + const formatDate = (timestamp) => { + const date = new Date(parseInt(timestamp) * 1000); + return new Intl.DateTimeFormat("fa-IR", { + year: "numeric", + month: "long", + day: "numeric", + hour: "2-digit", + minute: "2-digit", + }).format(date); + }; + + const formatAmount = (amount) => { + return new Intl.NumberFormat("fa-IR").format(parseInt(amount)); + }; + + if (loading) { + return ( + +
+
+
+

در حال بارگذاری...

+
+
+
+ ); + } + + if (error) { + return ( + +
+
+

{error}

+
+
+
+ ); + } + + if (!payment) { + return null; + } + + return ( + +
+
+

+ جزئیات پرداخت +

+ +
+ {/* وضعیت پرداخت */} +
+ وضعیت: + + {getStatusLabel(payment.status)} + +
+ + {/* مبلغ */} +
+ مبلغ: + + {formatAmount(payment.amount)} تومان + +
+ + {/* روش پرداخت */} +
+ روش پرداخت: + + {getPaymentMethodLabel(payment.payment_method)} + +
+ + {/* شناسه پرداخت */} +
+ شناسه پرداخت: + + {payment.uuid} + +
+ + {/* شماره مرجع */} + {payment.reference_id && ( +
+ شماره مرجع: + + {payment.reference_id} + +
+ )} + + {/* تاریخ ایجاد */} +
+ تاریخ ایجاد: + + {formatDate(payment.created)} + +
+ + {/* تاریخ آخرین تغییر */} +
+ + آخرین بروزرسانی: + + + {formatDate(payment.changed)} + +
+ + {/* نوع سرویس */} +
+ نوع سرویس: + + {payment.bundle === "appointment" ? "رزرو نوبت" : payment.bundle} + +
+
+ + {/* دکمه‌ها */} +
+ {payment.status === "pending" ? ( + <> + + + + ) : ( + payment.frontend_address && ( + + ) + )} +
+
+
+
+ ); +} diff --git a/components/appointment/paying/index.js b/components/appointment/paying/index.js index 8453e1e..18c97a4 100644 --- a/components/appointment/paying/index.js +++ b/components/appointment/paying/index.js @@ -46,7 +46,8 @@ function Paying({ setStep, appointmentId }) { const paymentPayload = { payment_method: selectedBank, bundle: "appointment", - entity_reference_id: appointmentId + entity_reference_id: appointmentId, + frontend_address: typeof window !== 'undefined' ? window.location.origin : '' }; const response = await request.postPayment(paymentPayload); diff --git a/services/response.js b/services/response.js index c6dc2df..e4916bc 100644 --- a/services/response.js +++ b/services/response.js @@ -68,6 +68,7 @@ export const request = { ), postAppointment: (data) => api.post(`api/v1/appointment`, data, { requireAuth: true }), postPayment: (data) => api.post(`api/v1/payment`, data, { requireAuth: true }), + getPayment: (uuid) => api.get(`api/v1/payment/${uuid}`, { requireAuth: true }), postDoctor: (data) => api.post("api/v1/doctor", data), postImageUpload: (data) => api.post("file/upload/clinic_pro/doctor/field_image", data, {