feat(panel): connect turns/user-account/add-doctor to real data
- انتقال adapterهای نماینده به lib/representationAdapters (server-safe، بدون وابستگی client مثل js-cookie/react-toastify) - turns: لیست از daily[] داشبورد ماهانه (ستون نام/تخصص خالی، بدون داده ساختگی) - user-account: حساب بانکی واقعی از bank_account نماینده (map به آرایه تککارته) - add-doctor: حذف import mock مرده (کامپوننت data مصرف نمیکرد) - رفع dead import اشتباه از turns/page در clinic/doctors که build را میشکست Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -1,8 +1,7 @@
|
|||||||
import AddDoctorPage from "@/components/panel/addDoctor";
|
import AddDoctorPage from "@/components/panel/addDoctor";
|
||||||
import Information from "@/data/information.json";
|
|
||||||
|
|
||||||
function AddDoctor() {
|
function AddDoctor() {
|
||||||
return <AddDoctorPage data={Information} />;
|
return <AddDoctorPage />;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default AddDoctor;
|
export default AddDoctor;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import DashboardPage from "@/components/panel/dashboard";
|
|||||||
import { cookies } from "next/headers";
|
import { cookies } from "next/headers";
|
||||||
import { fetchReq } from "@/lib/req";
|
import { fetchReq } from "@/lib/req";
|
||||||
import { safeJsonParse } from "@/lib/sanitize";
|
import { safeJsonParse } from "@/lib/sanitize";
|
||||||
import { adaptRepresentationDashboard } from "@/helper";
|
import { adaptRepresentationDashboard } from "@/lib/representationAdapters";
|
||||||
|
|
||||||
export const dynamic = "force-dynamic";
|
export const dynamic = "force-dynamic";
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,40 @@
|
|||||||
import TurnsPage from "@/components/panel/turns";
|
import TurnsPage from "@/components/panel/turns";
|
||||||
import Information from "@/data/information.json";
|
import { cookies } from "next/headers";
|
||||||
|
import { fetchReq } from "@/lib/req";
|
||||||
|
import { safeJsonParse } from "@/lib/sanitize";
|
||||||
|
import { adaptRepresentationDashboard } from "@/lib/representationAdapters";
|
||||||
|
|
||||||
function page() {
|
export const dynamic = "force-dynamic";
|
||||||
return <TurnsPage data={Information} />;
|
|
||||||
|
async function page() {
|
||||||
|
const API_URL = process.env.NEXT_PUBLIC_API_URL;
|
||||||
|
let dashboard = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const cookieStore = await cookies();
|
||||||
|
const userInfo = cookieStore.get("userInfo");
|
||||||
|
const accessToken = cookieStore.get("access_token");
|
||||||
|
|
||||||
|
if (userInfo && accessToken) {
|
||||||
|
const parsedUserInfo = safeJsonParse(userInfo.value);
|
||||||
|
const representationUuid = parsedUserInfo?.representation_uuid;
|
||||||
|
|
||||||
|
if (representationUuid) {
|
||||||
|
const now = new Date();
|
||||||
|
const year = now.getFullYear();
|
||||||
|
const month = now.getMonth() + 1;
|
||||||
|
|
||||||
|
dashboard = await fetchReq(
|
||||||
|
`${API_URL}/api/v1/representation/${representationUuid}/dashboard/monthly?year=${year}&month=${month}`,
|
||||||
|
{ headers: { Authorization: `Bearer ${accessToken.value}` } }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error fetching representation turns:", error);
|
||||||
|
}
|
||||||
|
|
||||||
|
return <TurnsPage data={adaptRepresentationDashboard(dashboard)} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default page;
|
export default page;
|
||||||
|
|||||||
@@ -1,9 +1,38 @@
|
|||||||
import UserAccountPage from "@/components/panel/userAccount";
|
import UserAccountPage from "@/components/panel/userAccount";
|
||||||
import Information from "@/data/information.json";
|
import { cookies } from "next/headers";
|
||||||
import Bank from "@/data/bank.json";
|
import { fetchReq } from "@/lib/req";
|
||||||
|
import { safeJsonParse } from "@/lib/sanitize";
|
||||||
|
import { adaptBankAccount } from "@/lib/representationAdapters";
|
||||||
|
|
||||||
function UserAccount() {
|
export const dynamic = "force-dynamic";
|
||||||
return <UserAccountPage data={{ information: Information, bank: Bank }} />;
|
|
||||||
|
async function UserAccount() {
|
||||||
|
const API_URL = process.env.NEXT_PUBLIC_API_URL;
|
||||||
|
let representation = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const cookieStore = await cookies();
|
||||||
|
const userInfo = cookieStore.get("userInfo");
|
||||||
|
const accessToken = cookieStore.get("access_token");
|
||||||
|
|
||||||
|
if (userInfo && accessToken) {
|
||||||
|
const parsedUserInfo = safeJsonParse(userInfo.value);
|
||||||
|
const representationUuid = parsedUserInfo?.representation_uuid;
|
||||||
|
|
||||||
|
if (representationUuid) {
|
||||||
|
representation = await fetchReq(
|
||||||
|
`${API_URL}/api/v1/representation/${representationUuid}`,
|
||||||
|
{ headers: { Authorization: `Bearer ${accessToken.value}` } }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error fetching representation account:", error);
|
||||||
|
}
|
||||||
|
|
||||||
|
const bank = adaptBankAccount(representation?.data?.bank_account);
|
||||||
|
|
||||||
|
return <UserAccountPage data={{ bank }} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default UserAccount;
|
export default UserAccount;
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import List from "./List";
|
import List from "./List";
|
||||||
import Head from "./head";
|
import Head from "./head";
|
||||||
import page from "@/app/panel/(layout)/turns/page";
|
|
||||||
|
|
||||||
function Doctors({ slug, doctors, pages }) {
|
function Doctors({ slug, doctors, pages }) {
|
||||||
const [page, setPage] = useState(pages?.current || 1);
|
const [page, setPage] = useState(pages?.current || 1);
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import Sidebar from "@/components/layoutPanel/sidebar";
|
|||||||
import UserDetail from "@/components/layoutPanel/userDetail";
|
import UserDetail from "@/components/layoutPanel/userDetail";
|
||||||
import { usePathname } from "next/navigation";
|
import { usePathname } from "next/navigation";
|
||||||
import BgGray from "@/components/layoutPanel/sidebar/BgGray";
|
import BgGray from "@/components/layoutPanel/sidebar/BgGray";
|
||||||
import { adaptRepresentationInfo } from "@/helper";
|
import { adaptRepresentationInfo } from "@/lib/representationAdapters";
|
||||||
|
|
||||||
function Content({ children, representationInfo }) {
|
function Content({ children, representationInfo }) {
|
||||||
const pathname = usePathname();
|
const pathname = usePathname();
|
||||||
|
|||||||
@@ -675,39 +675,3 @@ export function changeNumToDefault(str) {
|
|||||||
.replace(/[٠-٩]/g, d => "٠١٢٣٤٥٦٧٨٩".indexOf(d));
|
.replace(/[٠-٩]/g, d => "٠١٢٣٤٥٦٧٨٩".indexOf(d));
|
||||||
}
|
}
|
||||||
|
|
||||||
export function adaptRepresentationInfo(representationInfo) {
|
|
||||||
const data = representationInfo?.data ?? representationInfo ?? {};
|
|
||||||
|
|
||||||
return {
|
|
||||||
name: data.full_name ?? "",
|
|
||||||
src: data.avatar ?? "/assets/images/doctor.png",
|
|
||||||
detail: data.city_name ? `نماینده شهر ${data.city_name}` : "نماینده",
|
|
||||||
mobile_number: data.mobile_number ?? "",
|
|
||||||
commission_percent: data.commission_percent ?? null,
|
|
||||||
bank_account: data.bank_account ?? null,
|
|
||||||
city: { label: data.city_name ?? "" },
|
|
||||||
all_patients: null,
|
|
||||||
total_turns: null,
|
|
||||||
number_of_patients: null,
|
|
||||||
today_turns: null,
|
|
||||||
payments: null,
|
|
||||||
todays_activities: [],
|
|
||||||
list_of_doctors_appointments: [],
|
|
||||||
chart_amount_income: [],
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function adaptRepresentationDashboard(dashboard) {
|
|
||||||
const stats = dashboard?.data?.stats ?? dashboard?.stats ?? {};
|
|
||||||
const daily = Array.isArray(stats.daily) ? stats.daily : [];
|
|
||||||
|
|
||||||
return {
|
|
||||||
number_of_patients: stats.total_appointments ?? 0,
|
|
||||||
today_turns: daily.length ? daily[daily.length - 1].appointments ?? 0 : 0,
|
|
||||||
payments: stats.total_revenue_rials ?? 0,
|
|
||||||
commission_rials: stats.commission_rials ?? 0,
|
|
||||||
chart_amount_income: daily.map((d) => d.revenue ?? 0),
|
|
||||||
list_of_doctors_appointments: [],
|
|
||||||
todays_activities: [],
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -0,0 +1,66 @@
|
|||||||
|
import moment from "moment-jalaali";
|
||||||
|
|
||||||
|
const DEFAULT_AVATAR = "/assets/images/doctor.png";
|
||||||
|
|
||||||
|
function toJalali(date) {
|
||||||
|
if (!date) return "--";
|
||||||
|
return moment(date).format("jYYYY/jM/jD");
|
||||||
|
}
|
||||||
|
|
||||||
|
export function adaptRepresentationInfo(representationInfo) {
|
||||||
|
const data = representationInfo?.data ?? representationInfo ?? {};
|
||||||
|
|
||||||
|
return {
|
||||||
|
name: data.full_name ?? "",
|
||||||
|
src: data.avatar ?? DEFAULT_AVATAR,
|
||||||
|
detail: data.city_name ? `نماینده شهر ${data.city_name}` : "نماینده",
|
||||||
|
mobile_number: data.mobile_number ?? "",
|
||||||
|
commission_percent: data.commission_percent ?? null,
|
||||||
|
bank_account: data.bank_account ?? null,
|
||||||
|
city: { label: data.city_name ?? "" },
|
||||||
|
all_patients: null,
|
||||||
|
total_turns: null,
|
||||||
|
number_of_patients: null,
|
||||||
|
today_turns: null,
|
||||||
|
payments: null,
|
||||||
|
todays_activities: [],
|
||||||
|
list_of_doctors_appointments: [],
|
||||||
|
chart_amount_income: [],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function adaptRepresentationDashboard(dashboard) {
|
||||||
|
const stats = dashboard?.data?.stats ?? dashboard?.stats ?? {};
|
||||||
|
const daily = Array.isArray(stats.daily) ? stats.daily : [];
|
||||||
|
|
||||||
|
return {
|
||||||
|
number_of_patients: stats.total_appointments ?? 0,
|
||||||
|
today_turns: daily.length ? daily[daily.length - 1].appointments ?? 0 : 0,
|
||||||
|
payments: stats.total_revenue_rials ?? 0,
|
||||||
|
commission_rials: stats.commission_rials ?? 0,
|
||||||
|
chart_amount_income: daily.map((d) => d.revenue ?? 0),
|
||||||
|
list_of_doctors_appointments: daily.map((d) => ({
|
||||||
|
name: "",
|
||||||
|
expertise: "",
|
||||||
|
image: DEFAULT_AVATAR,
|
||||||
|
date: toJalali(d.date),
|
||||||
|
hour: "",
|
||||||
|
number_of_turns: d.appointments ?? 0,
|
||||||
|
})),
|
||||||
|
todays_activities: [],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function adaptBankAccount(bankAccount) {
|
||||||
|
if (!bankAccount) return [];
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
card_number: bankAccount.account_number ?? "",
|
||||||
|
shaba_number: bankAccount.iban ?? "",
|
||||||
|
bank: bankAccount.bank_name ?? "",
|
||||||
|
owner_name: bankAccount.owner_name ?? "",
|
||||||
|
status: true,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user