From e7c8501680a2d8cd1adb82dfb14a57145a4ff54d Mon Sep 17 00:00:00 2001
From: hamed <15238-genius.ha@users.noreply.drupalcode.org>
Date: Tue, 18 Nov 2025 22:21:47 +0330
Subject: [PATCH] refactor: enhance transaction and appointment handling with
pagination, status filtering, and improved data display
---
app/payment/[uuid]/page.js | 17 ++---
.../userAccount/sidebars/transactions/Card.js | 56 +++++++-------
.../userAccount/sidebars/transactions/Head.js | 60 +++++++++++++++
.../userAccount/sidebars/transactions/List.js | 67 +++++++++--------
.../sidebars/transactions/index.js | 75 ++++++++++++++++++-
.../userAccount/sidebars/turns/List.js | 12 ++-
.../userAccount/sidebars/turns/index.js | 60 ++++++++++++++-
helper/index.js | 12 +++
services/response.js | 2 +
9 files changed, 286 insertions(+), 75 deletions(-)
create mode 100644 components/dashboard/userAccount/sidebars/transactions/Head.js
diff --git a/app/payment/[uuid]/page.js b/app/payment/[uuid]/page.js
index a98bbd2..68e2c90 100644
--- a/app/payment/[uuid]/page.js
+++ b/app/payment/[uuid]/page.js
@@ -213,16 +213,13 @@ export default function PaymentDetailsPage() {
بروزرسانی وضعیت
>
- ) : (
- payment.frontend_address && (
-
- )
- )}
+ ) : null}
+
diff --git a/components/dashboard/userAccount/sidebars/transactions/Card.js b/components/dashboard/userAccount/sidebars/transactions/Card.js
index 3f5e2b1..77b78a2 100644
--- a/components/dashboard/userAccount/sidebars/transactions/Card.js
+++ b/components/dashboard/userAccount/sidebars/transactions/Card.js
@@ -1,41 +1,41 @@
import CircularLoading from "@/app/component/loading/Circular";
import TextLoading from "@/app/component/loading/Text";
import Image from "next/image";
+import { convertTimestampToJalali, convertTimestampToTime } from "@/helper";
+import Link from "next/link";
function Card({ data, loading }) {
return (
-
-
-
-
+
- {data.name}
+ {data.appointment_details?.doctor_name || "--"}
-
+
- {data.status === "success"
- ? "پرداخت شده"
- : data.status === "pending"
- ? "در انتظار"
- : "پرداخت نشده"}
-
+ variant="text"
+ >
+ {data.status === "received"
+ ? "پرداخت شده"
+ : data.status === "pending"
+ ? "در انتظار"
+ : "لغو شده"}
+
+
@@ -54,9 +54,9 @@ function Card({ data, loading }) {
تاریخ نوبت:
-
+
- {data.date}
+ {convertTimestampToJalali(data.appointment_details?.start_time)}
@@ -67,7 +67,7 @@ function Card({ data, loading }) {
- {data.time}
+ {convertTimestampToTime(data.appointment_details?.start_time)}
@@ -75,12 +75,12 @@ function Card({ data, loading }) {
- مبلغ پیش پرداخت:
+ مبلغ:
-
+
- {data.amount} تومان
+ {data.amount ? data.amount.toLocaleString('fa-IR') : "--"} تومان
diff --git a/components/dashboard/userAccount/sidebars/transactions/Head.js b/components/dashboard/userAccount/sidebars/transactions/Head.js
new file mode 100644
index 0000000..c3a9132
--- /dev/null
+++ b/components/dashboard/userAccount/sidebars/transactions/Head.js
@@ -0,0 +1,60 @@
+import Tabs from "@/app/component/Tabs";
+
+const listTab = ["همه", "در انتظار", "پرداخت شده", "لغو شده"];
+
+function Head({ status, setStatus }) {
+ const statusMap = {
+ 0: undefined, // all
+ 1: "pending",
+ 2: "received",
+ 3: "canceled",
+ };
+
+ const handleChange = (e, value) => {
+ setStatus(statusMap[value]);
+ };
+
+ const getCurrentIndex = () => {
+ const entries = Object.entries(statusMap);
+ const found = entries.find(([_, val]) => val === status);
+ return found ? parseInt(found[0]) : 0;
+ };
+
+ return (
+
+ );
+}
+
+export default Head;
diff --git a/components/dashboard/userAccount/sidebars/transactions/List.js b/components/dashboard/userAccount/sidebars/transactions/List.js
index cb2dc2c..37b1775 100644
--- a/components/dashboard/userAccount/sidebars/transactions/List.js
+++ b/components/dashboard/userAccount/sidebars/transactions/List.js
@@ -5,8 +5,11 @@ import Card from "./Card";
import TextLoading from "@/app/component/loading/Text";
import CustomLoading from "@/app/component/loading/Custom";
import CircularLoading from "@/app/component/loading/Circular";
+import { convertTimestampToJalali, convertTimestampToTime } from "@/helper";
+import Pagination from "@/app/component/Pagination";
+import Link from "next/link";
-function List({ user, loading }) {
+function List({ user, loading, page, totalPages, onPageChange }) {
const tableHead = [
"ردیف",
"شناسه",
@@ -45,26 +48,16 @@ function List({ user, loading }) {
component="th"
scope="row"
>
-
-
-
-
-
- {row.name}
-
-
+
+ {row.appointment_details?.doctor_name || "--"}
+
-
- {row.date}
+
+ {convertTimestampToJalali(row.appointment_details?.start_time)}
- {row.time}
+ {convertTimestampToTime(row.appointment_details?.start_time)}
- {row.amount}
+ {row.amount ? row.amount.toLocaleString('fa-IR') : "--"}
-
+
- {row.status === "success"
- ? "پرداخت شده"
- : row.status === "pending"
- ? "در انتظار"
- : "پرداخت نشده"}
-
+ variant="text"
+ >
+ {row.status === "received"
+ ? "پرداخت شده"
+ : row.status === "pending"
+ ? "در انتظار"
+ : "لغو شده"}
+
+
@@ -115,6 +109,15 @@ function List({ user, loading }) {
))}
+ {totalPages > 1 && (
+
+ )}
);
}
diff --git a/components/dashboard/userAccount/sidebars/transactions/index.js b/components/dashboard/userAccount/sidebars/transactions/index.js
index 6f1cc96..f112e6d 100644
--- a/components/dashboard/userAccount/sidebars/transactions/index.js
+++ b/components/dashboard/userAccount/sidebars/transactions/index.js
@@ -1,12 +1,85 @@
+"use client";
+
+import { useEffect, useState } from "react";
import List from "./List";
+import Head from "./Head";
+import { request } from "@/services/response";
+import Cookies from "js-cookie";
function Transactions({ user, loading }) {
+ const [payments, setPayments] = useState([]);
+ const [isLoading, setIsLoading] = useState(true);
+ const [page, setPage] = useState(1);
+ const [totalPages, setTotalPages] = useState(1);
+ const [status, setStatus] = useState(undefined); // undefined = all, 'pending', 'success', 'failed'
+
+ useEffect(() => {
+ const fetchPayments = async () => {
+ setIsLoading(true);
+ try {
+ const userInfo = Cookies.get("userInfo");
+ if (!userInfo) {
+ setIsLoading(false);
+ return;
+ }
+
+ const parsedData = JSON.parse(userInfo);
+ const userId = parsedData.id || parsedData.uuid;
+
+ if (!userId) {
+ setIsLoading(false);
+ return;
+ }
+
+ const params = {
+ page,
+ limit: 10,
+ };
+
+ if (status) {
+ params.status = status;
+ }
+
+ const response = await request.getMyPayments(userId, params);
+
+ if (response?.data) {
+ setPayments(response.data);
+ if (response.page) {
+ setTotalPages(response.page.totalPages);
+ }
+ }
+ } catch (error) {
+ console.error("Error fetching payments:", error);
+ } finally {
+ setIsLoading(false);
+ }
+ };
+
+ fetchPayments();
+ }, [page, status]);
+
+ const handlePageChange = (event, value) => {
+ setPage(value);
+ };
+
+ const handleStatusChange = (newStatus) => {
+ setStatus(newStatus);
+ setPage(1); // Reset to first page when status changes
+ };
+
return (
+
);
}
diff --git a/components/dashboard/userAccount/sidebars/turns/List.js b/components/dashboard/userAccount/sidebars/turns/List.js
index ed20f8d..2a3c78b 100644
--- a/components/dashboard/userAccount/sidebars/turns/List.js
+++ b/components/dashboard/userAccount/sidebars/turns/List.js
@@ -6,8 +6,9 @@ import Card from "./Card";
import CircularLoading from "@/app/component/loading/Circular";
import TextLoading from "@/app/component/loading/Text";
import CustomLoading from "@/app/component/loading/Custom";
+import Pagination from "@/app/component/Pagination";
-function List({ user, loading, setIsTurnsDetails }) {
+function List({ user, loading, setIsTurnsDetails, page, totalPages, onPageChange }) {
const tableHead = [
"ردیف",
"نام پزشک",
@@ -110,6 +111,15 @@ function List({ user, loading, setIsTurnsDetails }) {
/>
))}
+ {totalPages > 1 && (
+
+ )}
);
}
diff --git a/components/dashboard/userAccount/sidebars/turns/index.js b/components/dashboard/userAccount/sidebars/turns/index.js
index 0eda5cf..70d2e56 100644
--- a/components/dashboard/userAccount/sidebars/turns/index.js
+++ b/components/dashboard/userAccount/sidebars/turns/index.js
@@ -1,9 +1,60 @@
-import { useState } from "react";
+"use client";
+
+import { useEffect, useState } from "react";
import Head from "./Head";
import List from "./List";
+import { request } from "@/services/response";
+import Cookies from "js-cookie";
function Turns({ user, setIsTurnsDetails, loading }) {
const [isDone, setIsDone] = useState(true);
+ const [appointments, setAppointments] = useState([]);
+ const [isLoading, setIsLoading] = useState(true);
+ const [page, setPage] = useState(1);
+ const [totalPages, setTotalPages] = useState(1);
+
+ useEffect(() => {
+ const fetchAppointments = async () => {
+ setIsLoading(true);
+ try {
+ const userInfo = Cookies.get("userInfo");
+ if (!userInfo) {
+ setIsLoading(false);
+ return;
+ }
+
+ const parsedData = JSON.parse(userInfo);
+ const userId = parsedData.id || parsedData.uuid;
+
+ if (!userId) {
+ setIsLoading(false);
+ return;
+ }
+
+ const response = await request.getMyAppointments(userId, {
+ page,
+ limit: 10,
+ });
+
+ if (response?.data) {
+ setAppointments(response.data);
+ if (response.page) {
+ setTotalPages(response.page.totalPages);
+ }
+ }
+ } catch (error) {
+ console.error("Error fetching appointments:", error);
+ } finally {
+ setIsLoading(false);
+ }
+ };
+
+ fetchAppointments();
+ }, [page]);
+
+ const handlePageChange = (event, value) => {
+ setPage(value);
+ };
return (
@@ -12,9 +63,12 @@ function Turns({ user, setIsTurnsDetails, loading }) {
);
diff --git a/helper/index.js b/helper/index.js
index 15c18c2..9ec91d0 100644
--- a/helper/index.js
+++ b/helper/index.js
@@ -23,6 +23,18 @@ export const convertToJalali = (date) => {
return `${jalaliYear}/${jalaliMonth}/${jalaliDay}`;
};
+export const convertTimestampToJalali = (timestamp) => {
+ if (!timestamp) return "--";
+ const date = moment.unix(timestamp);
+ return date.format("jYYYY/jMM/jDD");
+};
+
+export const convertTimestampToTime = (timestamp) => {
+ if (!timestamp) return "--";
+ const date = moment.unix(timestamp);
+ return date.format("HH:mm");
+};
+
export const handleTwoLength = (value) =>
String(value).length === 1 ? `0${value}` : value;
diff --git a/services/response.js b/services/response.js
index e4916bc..ed7575d 100644
--- a/services/response.js
+++ b/services/response.js
@@ -67,8 +67,10 @@ export const request = {
removeTokenHead
),
postAppointment: (data) => api.post(`api/v1/appointment`, data, { requireAuth: true }),
+ getMyAppointments: (userId, params) => api.get(`api/v1/appointment/my-appointments/${userId}`, { params, requireAuth: true }),
postPayment: (data) => api.post(`api/v1/payment`, data, { requireAuth: true }),
getPayment: (uuid) => api.get(`api/v1/payment/${uuid}`, { requireAuth: true }),
+ getMyPayments: (userId, params) => api.get(`api/v1/payment/my-payments/${userId}`, { params, requireAuth: true }),
postDoctor: (data) => api.post("api/v1/doctor", data),
postImageUpload: (data) =>
api.post("file/upload/clinic_pro/doctor/field_image", data, {