change design and data list in doctor-item & handle component appointment in doctor-item & handle functionality date-picker & fix bug appointment page & add req get appointment list

This commit is contained in:
Ehsan
2025-07-09 03:05:48 +03:30
parent f951128074
commit c6e2657e45
57 changed files with 442 additions and 445 deletions
@@ -0,0 +1,20 @@
import DatePicker from "@/app/component/date/datePicker";
import { request } from "@/services/response";
import { useEffect } from "react";
function SelectDatePicker() {
useEffect(() => {
request
.getAppointment(47, 1753859133)
.then((res) => {
console.log(res);
})
.catch((err) => {
console.log(err);
});
});
return <DatePicker />;
}
export default SelectDatePicker;
@@ -19,11 +19,11 @@ function Date({ doctor, setStep }) {
isError={isError}
/>
<Time
isStep={doctor.multiwork ? locateVisit : true}
isStep={doctor?.multiwork ? locateVisit : true}
locateVisit={locateVisit}
/>
<Hour
isStep={doctor.multiwork ? locateVisit : true}
isStep={doctor?.multiwork ? locateVisit : true}
setLocateVisit={setLocateVisit}
locateVisit={locateVisit}
setIsError={setIsError}
@@ -5,16 +5,16 @@ import { useState } from "react";
import Content from "./Content";
import Layout from "@/components/layout";
import doctors from "@/data/doctors.json";
import Date from "@/components/booking/date";
import Date from "@/components/appointment/date";
import RegisterPage from "@/components/register";
import Paying from "@/components/booking/paying";
import Detail from "@/components/booking/detail";
import FailedPay from "@/components/booking/failedPay";
import Paying from "@/components/appointment/paying";
import Detail from "@/components/appointment/detail";
import FailedPay from "@/components/appointment/failedPay";
import LogInPage from "@/components/register/LogInPage";
import SuccessPay from "@/components/booking/successPay";
import SuccessPay from "@/components/appointment/successPay";
import VerificationPage from "@/components/register/verificationPage";
function BookingPage({ slug, matchedCity }) {
function AppointmentPage({ slug, matchedCity }) {
const doctor = doctors.find((item) => item.id === +slug);
const [step, setStep] = useState(0);
@@ -69,4 +69,4 @@ function BookingPage({ slug, matchedCity }) {
);
}
export default BookingPage;
export default AppointmentPage;
@@ -1,7 +1,7 @@
function Address({ doctor }) {
return (
<ul className="hidden mt-[4px] lg:flex flex-col">
{doctor.address.map((item, idx) => (
{doctor?.address?.map((item, idx) => (
<li key={idx}>
<div className="flex py-[12px] text-[#616161] text-[14px] items-start justify-start">
<p className="font-bold min-w-[115px]">{`${item.name}: `}</p>
@@ -8,17 +8,17 @@ function Head({ doctor }) {
w-[48px] sm:w-[51px] md:w-[54px] lg:w-[56px]
h-[48px] sm:h-[51px] md:h-[54px] lg:h-[56px]
"
src={doctor.img}
src={doctor?.img}
alt="profile"
height={56}
width={56}
/>
<div className="flex flex-col items-start justify-start gap-[8px]">
<h2 className="text-[#3B3B3B] text-[12px] md:text-[14px] font-bold">
{doctor.name}
{doctor?.name}
</h2>
<h3 className="text-[#525252] text-[12px] md:text-[14px] font-medium">
تخصص: {doctor.expertise}
تخصص: {doctor?.expertise}
</h3>
</div>
</div>
@@ -1,7 +0,0 @@
import DatePicker from "@/app/component/date/datePicker";
function SelectDatePicker() {
return <DatePicker />;
}
export default SelectDatePicker;
@@ -13,6 +13,7 @@ import FamilyHistory from "./familyHistory";
import Relatives from "./relatives";
import { removeAdditionalKeysDashboard } from "@/helper";
import Cookies from "js-cookie";
import LoadingComponent from "@/app/component/LoadingComponent";
function DetailUser({ user, isTurnsDetails, setIsTurnsDetails }) {
const [tab, setTab] = useState(0);
@@ -1,6 +1,6 @@
import ArrowLeftWhiteD from "@/components/icons/ArrowLeftWhiteD";
import {
convertJalaliTimestamp,
changeDateType,
handleTimeExpiresToken,
removeAdditionalKeysDashboard,
} from "@/helper";
@@ -24,25 +24,9 @@ function ButtonSendData({
setLoading(false);
};
const changeDateType = (data) => {
const newData = data;
const splitedDate = newData.birthday.split("/");
newData.birthday = convertJalaliTimestamp(
{
jy: Number(splitedDate[0]),
jm: Number(splitedDate[1]),
jd: Number(splitedDate[2]),
},
true
);
return newData;
};
const postData = () => {
console.log(changeDateType(information));
request
.postUserProfile(information)
.postUserProfile(changeDateType(information, false))
.then((response) => {
if (response.uuid) {
const formData = new URLSearchParams();
@@ -84,11 +68,10 @@ function ButtonSendData({
const patchData = () => {
const usedKays = removeAdditionalKeysDashboard(information);
console.log(changeDateType(information));
request
.patchUserProfile(
usedKays,
changeDateType(usedKays, true),
information?.uuid,
Cookies.get("access_token")
)
@@ -1,8 +1,10 @@
function Content({ isConfirmed, children, title, error }) {
function Content({ isConfirmed, children, title, error, req }) {
return (
<div className="flex w-full flex-col items-start justify-start gap-[8px] sm:gap-[3px] md:gap-[7px] lg:gap-[9px]">
<div className="flex min-h-[32px] items-center justify-start gap-[8px] md:gap-[6px] lg:gap-[4px]">
<p className="text-[#525252] text-[14px] font-medium">{title}</p>
<p className="text-[#525252] text-[14px] font-medium">
{title} {req && "*"}
</p>
{isConfirmed && (
<p
className="py-[4px] md:py-[2px] px-[5px] bg-[#05BA58] rounded-[40px] text-[#FFF]
@@ -20,8 +20,6 @@ function Form({ insurance, errors, changeData, information }) {
list.find((g) => g.id === information[name]);
const parsedUserInfo = getParsedUserInfo();
console.log(information);
return (
<div className="grid grid-cols-1 lg:grid-cols-2 gap-x-[24px] gap-y-[10px]">
<Content title="شماره موبایل" isConfirmed={true}>
@@ -35,8 +33,14 @@ function Form({ insurance, errors, changeData, information }) {
data={parsedUserInfo?.username}
/>
</Content>
<Content error={errors?.national_code} title="کد ملی" isConfirmed={false}>
<Content
req={true}
error={errors?.national_code}
title="کد ملی"
isConfirmed={false}
>
<Field
req={true}
error={errors?.national_code}
type="number"
iconGray={true}
@@ -47,7 +51,7 @@ function Form({ insurance, errors, changeData, information }) {
disable={information?.prev_data}
/>
</Content>
<Content error={errors?.name} title="نام" isConfirmed={false}>
<Content req={true} error={errors?.name} title="نام" isConfirmed={false}>
<Field
error={errors?.name}
isTransparent={true}
@@ -57,7 +61,12 @@ function Form({ insurance, errors, changeData, information }) {
name="name"
/>
</Content>
<Content error={errors?.family} title="نام خانوادگی" isConfirmed={false}>
<Content
req={true}
error={errors?.family}
title="نام خانوادگی"
isConfirmed={false}
>
<Field
error={errors?.family}
isTransparent={true}
@@ -67,7 +76,7 @@ function Form({ insurance, errors, changeData, information }) {
name="family"
/>
</Content>
<Content error={errors?.gender} title="جنسیت">
<Content req={true} error={errors?.gender} title="جنسیت">
<AutoSelector
error={errors?.gender}
updateData={(name, data) =>
@@ -79,7 +88,7 @@ function Form({ insurance, errors, changeData, information }) {
list={gender}
/>
</Content>
<Content error={errors?.birthday} title="تاریخ تولد">
<Content req={true} error={errors?.birthday} title="تاریخ تولد">
<DateBirthday
error={errors?.birthday}
data={information?.birthday}
@@ -87,7 +96,12 @@ function Form({ insurance, errors, changeData, information }) {
changeData={changeData}
/>
</Content>
<Content error={errors?.fathers_name} title="نام پدر" isConfirmed={false}>
<Content
req={true}
error={errors?.fathers_name}
title="نام پدر"
isConfirmed={false}
>
<Field
error={errors?.fathers_name}
isTransparent={true}
@@ -97,7 +111,7 @@ function Form({ insurance, errors, changeData, information }) {
name="fathers_name"
/>
</Content>
<Content error={errors?.basic_insurance} title="نوع بیمه">
<Content req={true} error={errors?.basic_insurance} title="نوع بیمه">
<AutoSelector
error={errors?.basic_insurance}
updateData={(name, val) => {
@@ -121,6 +135,7 @@ function Form({ insurance, errors, changeData, information }) {
isConfirmed={false}
>
<Field
req={true}
error={errors?.insurance_id}
isTransparent={true}
iconGray={true}
@@ -130,7 +145,7 @@ function Form({ insurance, errors, changeData, information }) {
name="insurance_id"
/>
</Content>
<Content error={errors?.blood_type} title="گروه خونی">
<Content req={true} error={errors?.blood_type} title="گروه خونی">
<AutoSelector
error={errors?.blood_type}
updateData={(name, value) =>
@@ -142,7 +157,7 @@ function Form({ insurance, errors, changeData, information }) {
list={blood_group}
/>
</Content>
<Content error={errors?.marital_status} title="وضعیت تاهل">
<Content req={true} error={errors?.marital_status} title="وضعیت تاهل">
<AutoSelector
error={errors?.marital_status}
updateData={(name, value) =>
@@ -164,7 +179,7 @@ function Form({ insurance, errors, changeData, information }) {
name="home_phone"
/>
</Content>
<Content error={errors?.education} title="تحصیلات">
<Content req={true} error={errors?.education} title="تحصیلات">
<AutoSelector
error={errors?.education}
updateData={(name, value) =>
@@ -176,7 +191,7 @@ function Form({ insurance, errors, changeData, information }) {
list={education}
/>
</Content>
<Content error={errors?.job} title="شغل">
<Content req={true} error={errors?.job} title="شغل">
<AutoSelector
error={errors?.job}
updateData={(name, value) =>
@@ -2,13 +2,15 @@ import { useEffect, useState } from "react";
import Form from "./form";
import { request } from "@/services/response";
import ButtonSendData from "./ButtonSendData";
import { getParsedUserInfo } from "@/helper";
import { changeDateType, getParsedUserInfo } from "@/helper";
import { disease } from "./form/disease";
import LoadingComponent from "@/app/component/LoadingComponent";
function Information({ information, setInformation }) {
const [loading, setLoading] = useState(false);
const [insurance, setInsurance] = useState();
const [errors, setErrors] = useState({});
const [loadingInfo, setLoadingInfo] = useState(true);
useEffect(() => {
const parsedUserInfo = getParsedUserInfo();
@@ -23,12 +25,17 @@ function Information({ information, setInformation }) {
request
.getUserProfile(parsedUserInfo.uuid)
.then((res) => {
const changedData = res;
setLoadingInfo(false);
let changedData = res;
changedData.basic_insurance = [Number(res?.basic_insurance?.id)];
changedData.prev_data = true;
changedData = changeDateType(changedData, false);
setInformation(changedData);
})
.catch((err) => {
setLoadingInfo(false);
if (err?.response?.data === "Entity not found") {
setInformation({
prev_data: false,
@@ -43,6 +50,8 @@ function Information({ information, setInformation }) {
});
}
});
} else {
setLoadingInfo(false);
}
}, []);
@@ -60,22 +69,24 @@ function Information({ information, setInformation }) {
};
return (
<div className="opacity-page">
<Form
errors={errors}
insurance={insurance}
changeData={changeData}
information={information}
/>
<ButtonSendData
setInformation={setInformation}
information={information}
setLoading={setLoading}
setErrors={setErrors}
loading={loading}
errors={errors}
/>
</div>
<LoadingComponent loading={loadingInfo}>
<div className="opacity-page">
<Form
errors={errors}
insurance={insurance}
changeData={changeData}
information={information}
/>
<ButtonSendData
setInformation={setInformation}
information={information}
setLoading={setLoading}
setErrors={setErrors}
loading={loading}
errors={errors}
/>
</div>
</LoadingComponent>
);
}
@@ -9,7 +9,6 @@ function Relatives({ data, changeData, loading, updateData }) {
const tableHead = ["ردیف", "نام", "نسبت", "شماره تماس", "آدرس", ""];
const centerTable = [0];
const [open, setOpen] = useState(false);
console.log(relatives);
return (
<div className="opacity-page">
@@ -24,7 +24,6 @@ function ModalAddRelatives({ open, setOpen, changeData, loading, updateData }) {
setNewItem(contentItem);
handleClose();
};
console.log(newItem);
return (
<>
@@ -7,7 +7,7 @@ import Image from "next/image";
import Link from "next/link";
import React from "react";
function ItemAppointment({ turn, doctor, loading }) {
function ItemAppointment({ turn, loading }) {
return (
<li
key={turn.id}
@@ -17,17 +17,19 @@ function ItemAppointment({ turn, doctor, loading }) {
<span className="block w-full h-px bg-[#EFEFEF] my-4"></span>
<div className="flex items-center justify-start gap-3">
<CircularLoading width={56} height={56} loading={loading}>
<Image src={doctor?.img} width={56} height={56} alt="doctor" />
<Image src={turn?.img || ""} width={56} height={56} alt="doctor" />
</CircularLoading>
<div className="flex flex-col items-start justify-center gap-2">
<TextLoading width={60} height={15} loading={loading}>
<p className="text-[#3B3B3B] text-[14px] font-bold">
{doctor?.name}
</p>
<p className="text-[#3B3B3B] text-[14px] font-bold">{turn?.name}</p>
</TextLoading>
<TextLoading width={65} height={15} loading={loading}>
<p className="text-[#525252] text-[14px] font-medium">
تخصص: {doctor?.expertise}
تخصص:
{turn?.expertise?.map(
(item, idx) =>
`${item.name} ${turn.expertise.length === idx + 1 ? "" : "|"} `
)}
</p>
</TextLoading>
</div>
@@ -41,7 +43,7 @@ function ItemAppointment({ turn, doctor, loading }) {
</p>
</TextLoading>
</div>
<Link href={loading ? "#" : `/booking/${turn.id}`}>
<Link href={loading ? "#" : `/appointment/${turn.id}`}>
<Button
variant="contained"
className="!py-2 !px-3 xl:!px-6 gap-1"
+5 -13
View File
@@ -1,24 +1,16 @@
"use client";
import turns from "@/data/turns.json";
import { Button } from "@mui/material";
import ItemAppointment from "./ItemAppointment";
import ArrowLeftD from "@/components/icons/ArrowLeftD";
import Link from "next/link";
function AppointmentList({ doctor, loading }) {
const itemActive = turns[0];
function AppointmentList({ doctors, loading }) {
return (
<>
<ul className="hidden sticky top-[122px] sm:top-[150px] mt:top-[178px] lg:top-[206px] lg:flex w-[38%] flex-col justify-start items-center gap-8">
{[turns[0]].map((item) => (
<ItemAppointment
turn={item}
key={item.id}
doctor={doctor}
loading={loading}
/>
{doctors?.map((item) => (
<ItemAppointment turn={item} key={item.id} loading={loading} />
))}
</ul>
<div
@@ -26,9 +18,9 @@ function AppointmentList({ doctor, loading }) {
border-solid bottom-0 right-0 w-full p-4 flex items-center justify-between"
>
<p className="text-[#05BA58] text-[11px] font-normal">
اولین نوبت آزاد: {itemActive.first_free_turn}
اولین نوبت آزاد: {doctors[0]?.free_turn}
</p>
<Link href={`/booking/${itemActive.id}`}>
<Link href={`/appointment/${doctors[0]?.id}`}>
<Button
variant="contained"
className="!py-2 !px-4 gap-1 !text-[14px] !font-medium"
+1 -1
View File
@@ -56,7 +56,7 @@ function Share({ data }) {
<p className="text-[#525252] text-[11px] md:text-[12px] lg:text-[14px] font-normal">
شما می توانید این پزشک را با دیگران به اشتراک بگذارید:
</p>
<List data={data} hiddenRef={hiddenRef} />
<List hiddenRef={hiddenRef} />
</Box>
</Modal>
</div>
+7 -3
View File
@@ -15,7 +15,7 @@ function Title({ doctor }) {
w-[40px] sm:w-[81px] md:w-[123px] lg:w-[164px]
h-[40px] sm:h-[81px] md:h-[123px] lg:h-[164px]
"
src={doctor?.img}
src={doctor?.img[0]?.url}
alt="img-doctor"
height={164}
width={164}
@@ -24,12 +24,16 @@ function Title({ doctor }) {
<div className="flex flex-col items-center lg:items-start gap-[8px] lg:gap-[16px]">
<TextLoading width={90} height={20}>
<h1 className="text-[#3B3B3B] text-[14px] sm:text-[16px] md:text-[18px] lg:text-[20px] font-bold">
{doctor?.title}
{doctor?.name}
</h1>
</TextLoading>
<TextLoading width={100} height={20}>
<h3 className="text-[#525252] text-[14px] md:text-[16px] font-medium">
تخصص: {doctor?.expertise}
تخصص:
{doctor?.expertise?.map(
(item, idx) =>
`${item.name} ${doctor.expertise.length === idx + 1 ? "" : "|"} `
)}
</h3>
</TextLoading>
<div className="flex items-center justify-start gap-11">
@@ -49,7 +49,7 @@ function AboutDcotor({ doctor }) {
<span className="w-2 h-2 bg-[#F17732] rounded-full"></span>
<TextLoading width={70} height={18}>
<h4 className="text-[#616161] text-[16px] font-normal text-nowrap">
{item}
{item.name}
</h4>
</TextLoading>
</li>
@@ -59,7 +59,7 @@ function ModalAnswer({ doctor }) {
multiline={true}
title="نظر خود را بنویسید..."
/>
<Link href={`/booking/${doctor?.id}`} className="!mr-auto">
<Link href={`/appointment/${doctor?.id}`} className="!mr-auto">
<Button
variant="contained"
className="!py-2.5 !px-4 gap-1 !text-[14px] !font-medium !mt-[32px] !shadownon"
+7 -4
View File
@@ -4,16 +4,19 @@ import Share from "./detailDoctor/Share";
import CustomLoading from "@/app/component/loading/Custom";
import Poster from "./poster";
function DoctorPage({ doctor }) {
function DoctorPage({ doctor, doctors }) {
return (
<div className="pt-[92px] sm:pt-[120px] mt:pt-[148px] lg:pt-[176px] mt-[px] padding-responsive">
<div className="flex items-center justify-between">
<CustomLoading width={180} height={25}>
<div className="flex items-center justify-start text-[14px] md:text-[16px] font-normal">
<h2 className="text-[#9B9B9B] text-nowrap">
متخصص {doctor?.expertise} {" >"}
{doctor?.expertise?.map(
(item, idx) =>
`${item.name} ${doctor.expertise.length === idx + 1 ? ">" : "|"} `
)}
</h2>
<p className="text-[#525252] text-nowrap mr-1">{doctor?.title}</p>
<p className="text-[#525252] text-nowrap mr-1">{doctor?.name}</p>
</div>
</CustomLoading>
<div className="flex lg:hidden">
@@ -22,7 +25,7 @@ function DoctorPage({ doctor }) {
</div>
<div className="flex items-start justify-center gap-6 mt-[30px]">
<DetailDoctor doctor={doctor} />
<AppointmentList doctor={doctor} />
<AppointmentList doctors={doctors} />
</div>
</div>
);
+1 -1
View File
@@ -12,7 +12,7 @@ function Services({ data }) {
{data?.specialties?.map((item, idx) => (
<li key={idx} className="flex items-center justify-start gap-[4px]">
<CircleOrangeSm />
<p className="text-[16px] font-normal text-[#E7EEF6]">{item}</p>
<p className="text-[16px] font-normal text-[#E7EEF6]">{item.name}</p>
</li>
))}
</ul>
+5 -1
View File
@@ -18,7 +18,11 @@ function Poster({ data }) {
{data?.name}
</p>
<p className="text-[24px] mt-[20px] text-[#E7EEF6] font-bold">
تخصص: {data?.expertise}
تخصص:
{data?.expertise?.map(
(item, idx) =>
`${item.name} ${data.expertise.length === idx + 1 ? "" : "|"} `
)}
</p>
<Services data={data} />
<Address data={data} />
@@ -1,11 +1,8 @@
"use client";
import { DatePicker } from "jalaali-react-date-picker";
import moment from "moment-jalaali";
function Date() {
const todayJalaali = moment().format("jYYYY/jMM/jDD");
return (
<div className="flex justify-center sm-datepicker active-today jalali-dashboard">
<DatePicker