get data with filter location for first time, get comment of doctor and show in doctor page, handle new comment
This commit is contained in:
@@ -33,7 +33,11 @@ function ItemDoctor({ doctor }) {
|
||||
</TextLoading>
|
||||
<TextLoading width={120} height={15}>
|
||||
<p className="text-[#616161] text-[14px] font-normal">
|
||||
تخصص: {doctor?.expertise}
|
||||
تخصص:
|
||||
{doctor?.specialties?.map(
|
||||
(item, idx) =>
|
||||
`${item.name} ${doctor.specialties.length === idx + 1 ? "" : "|"} `
|
||||
)}
|
||||
</p>
|
||||
</TextLoading>
|
||||
<CustomLoading width={100} height={25}>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Slider } from "@mui/material";
|
||||
import { useState } from "react";
|
||||
|
||||
function ProgressChange({ data }) {
|
||||
function ProgressChange({ data, changeData, parent }) {
|
||||
const [value, setValue] = useState(70);
|
||||
|
||||
return (
|
||||
@@ -10,9 +10,12 @@ function ProgressChange({ data }) {
|
||||
{data.label}
|
||||
</p>
|
||||
<Slider
|
||||
defaultValue={value}
|
||||
defaultValue={data.progress}
|
||||
className="!w-full lg:!w-[265px] !rounded-[10px] !h-[11px]"
|
||||
onChange={(e) => setValue(e.target.value)}
|
||||
onChange={(e) => {
|
||||
setValue(e.target.value);
|
||||
changeData(parent, data.name, e.target.value);
|
||||
}}
|
||||
sx={{
|
||||
"& .MuiSlider-rail": {
|
||||
background: "#E8E8E8",
|
||||
@@ -32,7 +35,7 @@ function ProgressChange({ data }) {
|
||||
},
|
||||
}}
|
||||
/>
|
||||
<p className="text-[#525252] text-[20px] font-medium w-[30px] min-w-[32px]">
|
||||
<p className="text-[#525252] text-[20px] font-medium w-[30px] min-w-[32px] text-center">
|
||||
{value}
|
||||
</p>
|
||||
</li>
|
||||
|
||||
@@ -13,10 +13,13 @@ function ItemUser({ update, setUpdate, isReply, list, setList, data }) {
|
||||
const handleLike = (lengthLike, data, nameLike, nameIsLike) => {
|
||||
if (nameIsLike === "is_like" && data.is_dislike) {
|
||||
data.is_dislike = false;
|
||||
data.dislike--;
|
||||
} else if (nameIsLike === "is_dislike" && data.is_like) {
|
||||
data.is_like = false;
|
||||
data.like--;
|
||||
data.like_status.dislike_count--;
|
||||
} else if (
|
||||
nameIsLike === "is_dislike" &&
|
||||
data.like_status.current_user_like.like
|
||||
) {
|
||||
data.like_status.current_user_like.like = false;
|
||||
data.like_status.like_count--;
|
||||
}
|
||||
data[nameLike] = lengthLike;
|
||||
data[nameIsLike] = !data[nameIsLike];
|
||||
@@ -28,14 +31,14 @@ function ItemUser({ update, setUpdate, isReply, list, setList, data }) {
|
||||
<div className="flex items-center justify-start gap-2">
|
||||
<Image
|
||||
className="!w-[32px] !h-[32px] sm:!w-[35px] sm:!h-[35px] md:!h-[37px] md:!w-[37px] lg:!w-[40px] lg:!h-[40px]"
|
||||
src={data.profile}
|
||||
src={data.author?.picture[0]?.url}
|
||||
width={40}
|
||||
height={40}
|
||||
alt="profile"
|
||||
/>
|
||||
<div className="flex flex-col items-start justify-center gap-[8px]">
|
||||
<p className="text-[#343A40] text-[14px] md:text-[16px] font-medium">
|
||||
{data.name}
|
||||
{data.author.real_name}
|
||||
</p>
|
||||
<p className="text-[#7E7E7E] text-[12px] md:text-[14px] font-medium">
|
||||
3 روز پیش
|
||||
@@ -52,17 +55,23 @@ function ItemUser({ update, setUpdate, isReply, list, setList, data }) {
|
||||
className="cursor-pointer"
|
||||
onClick={() =>
|
||||
handleLike(
|
||||
data.is_like ? data.like - 1 : data.like + 1,
|
||||
data.like_status.current_user_like.like
|
||||
? data.like_status.like_count - 1
|
||||
: data.like_status.like_count + 1,
|
||||
data,
|
||||
"like",
|
||||
"is_like"
|
||||
)
|
||||
}
|
||||
>
|
||||
{data.is_like ? <BoldLikeComment /> : <LikeComment />}
|
||||
{data.like_status.current_user_like.like ? (
|
||||
<BoldLikeComment />
|
||||
) : (
|
||||
<LikeComment />
|
||||
)}
|
||||
</div>
|
||||
<p className="text-[#6C757D] text-[12px] font-normal select-none">
|
||||
{data.like}
|
||||
{data.like_status.like_count || ""}
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex items-center justify-start gap-1">
|
||||
@@ -70,7 +79,9 @@ function ItemUser({ update, setUpdate, isReply, list, setList, data }) {
|
||||
className="cursor-pointer"
|
||||
onClick={() =>
|
||||
handleLike(
|
||||
data.is_dislike ? data.dislike - 1 : data.dislike + 1,
|
||||
data.is_dislike
|
||||
? data.like_status.dislike_count - 1
|
||||
: data.like_status.dislike_count + 1,
|
||||
data,
|
||||
"dislike",
|
||||
"is_dislike"
|
||||
@@ -80,7 +91,7 @@ function ItemUser({ update, setUpdate, isReply, list, setList, data }) {
|
||||
{data.is_dislike ? <BoldDisLikeComment /> : <DisLikeComment />}
|
||||
</div>
|
||||
<p className="text-[#6C757D] text-[12px] font-normal select-none">
|
||||
{data.dislike}
|
||||
{data.like_status.dislike_count || ""}
|
||||
</p>
|
||||
</div>
|
||||
<Button
|
||||
@@ -107,7 +118,7 @@ function ItemUser({ update, setUpdate, isReply, list, setList, data }) {
|
||||
ارسال پاسخ
|
||||
</Button>
|
||||
</div>
|
||||
{!!data.replays.length && (
|
||||
{!!data.replies.length && (
|
||||
<div className="flex items-center justify-start gap-1 my-2">
|
||||
<Button
|
||||
className="!text-[#0FA1B3] !text-[12px] !font-medium"
|
||||
@@ -116,7 +127,7 @@ function ItemUser({ update, setUpdate, isReply, list, setList, data }) {
|
||||
setUpdate(!update);
|
||||
}}
|
||||
>
|
||||
مشاهده پاسخ ها ({data.replays.length})
|
||||
مشاهده پاسخ ها ({data.replies.length})
|
||||
<div
|
||||
className={`!mr-1 ${
|
||||
data.is_open_reply ? "!rotate-0" : "!rotate-180"
|
||||
@@ -128,10 +139,10 @@ function ItemUser({ update, setUpdate, isReply, list, setList, data }) {
|
||||
</div>
|
||||
)}
|
||||
<ul
|
||||
className={`flex mr-12 flex-col justify-center transition-all duration-500 overflow-hidden items-start gap-12 w-full
|
||||
${data.is_open_reply ? "max-h-screen mt-12" : "max-h-0"}`}
|
||||
className={`flex pr-12 flex-col justify-center transition-all duration-500 overflow-hidden items-start gap-12 w-full
|
||||
${data.is_open_reply ? "max-h-fit mt-12" : "max-h-0"}`}
|
||||
>
|
||||
{data.replays.map((item, idx) => (
|
||||
{data.replies.map((item, idx) => (
|
||||
<ItemUser
|
||||
key={idx}
|
||||
data={item}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import { useState } from "react";
|
||||
import ItemUser from "./ItemUser";
|
||||
|
||||
function Comment({ data }) {
|
||||
function Comment({ data, comments }) {
|
||||
const [list, setList] = useState(data?.comments);
|
||||
const [update, setUpdate] = useState(false);
|
||||
|
||||
@@ -12,9 +12,9 @@ function Comment({ data }) {
|
||||
false && "w-full"
|
||||
}`}
|
||||
>
|
||||
{data &&
|
||||
!!data?.comments?.length &&
|
||||
data?.comments.map((item, idx) => (
|
||||
{comments &&
|
||||
comments.length &&
|
||||
comments.map((item, idx) => (
|
||||
<ItemUser
|
||||
key={idx}
|
||||
list={list}
|
||||
|
||||
@@ -5,6 +5,7 @@ import axios from "axios";
|
||||
async function Doctor({ params: { slug } }) {
|
||||
let doctors = null;
|
||||
let doctor = null;
|
||||
let comments = null;
|
||||
try {
|
||||
const resDoctors = await axios.get(
|
||||
"https://back-dev.clinic-pro.ir/api/v1/doctors?active=1"
|
||||
@@ -15,6 +16,12 @@ async function Doctor({ params: { slug } }) {
|
||||
|
||||
doctor = resDoctor.data;
|
||||
doctors = resDoctors.data.data;
|
||||
if (doctor) {
|
||||
const resComments = await axios.get(
|
||||
`https://back-dev.clinic-pro.ir/api/v1/clinicpro/comments/${doctor.id}`
|
||||
);
|
||||
comments = resComments?.data?.data;
|
||||
}
|
||||
} catch (error) {
|
||||
// console.error("problem with req:", error.message);
|
||||
// return redirect("/unauthorized");
|
||||
@@ -22,7 +29,7 @@ async function Doctor({ params: { slug } }) {
|
||||
|
||||
return (
|
||||
<Layout>
|
||||
<DoctorPage doctor={doctor} doctors={doctors} />
|
||||
<DoctorPage doctor={doctor} doctors={doctors} comments={comments} />
|
||||
</Layout>
|
||||
);
|
||||
}
|
||||
|
||||
+8
-1
@@ -8,8 +8,15 @@ async function Doctors({ searchParams }) {
|
||||
|
||||
let doctors = null;
|
||||
try {
|
||||
const params = {};
|
||||
|
||||
if (matchedCity) params.city = matchedCity;
|
||||
if (matchedState) params.state = matchedState;
|
||||
const response = await axios.get(
|
||||
"https://back-dev.clinic-pro.ir/api/v1/doctors"
|
||||
"https://back-dev.clinic-pro.ir/api/v1/doctors",
|
||||
{
|
||||
// params,
|
||||
}
|
||||
);
|
||||
doctors = response.data.data;
|
||||
} catch (error) {
|
||||
|
||||
@@ -2,7 +2,7 @@ import Chart from "./chart";
|
||||
import Comment from "@/app/component/comment";
|
||||
import ModalAnswer from "./modal/ModalAnswer";
|
||||
|
||||
function Comments({ doctor }) {
|
||||
function Comments({ doctor, comments }) {
|
||||
return (
|
||||
<div className="mt-[24px] sm:mt-[27px] md:mt-[29px] lg:mt-[32px]">
|
||||
<a
|
||||
@@ -19,7 +19,7 @@ function Comments({ doctor }) {
|
||||
<ModalAnswer doctor={doctor} />
|
||||
</div>
|
||||
<Chart doctor={doctor} />
|
||||
<Comment data={doctor} />
|
||||
<Comment data={doctor} comments={comments} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -7,12 +7,82 @@ import CloseModalD from "@/components/icons/CloseModalD";
|
||||
import Field from "@/app/component/fields/Field";
|
||||
import ArrowLeftD from "@/components/icons/ArrowLeftD";
|
||||
import ProgressChange from "@/app/component/ProgressChange";
|
||||
import ProgressDetail from "@/data/progress_detail.json";
|
||||
import Link from "next/link";
|
||||
import { request } from "@/services/response";
|
||||
|
||||
function ModalAnswer({ doctor }) {
|
||||
const [open, setOpen] = useState(false);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const handleOpen = () => setOpen(true);
|
||||
const handleClose = () => setOpen(false);
|
||||
const [comment, setComment] = useState({
|
||||
rate: ProgressDetail,
|
||||
detail: {
|
||||
comment: "",
|
||||
doctor_id: doctor?.id,
|
||||
},
|
||||
});
|
||||
const changeData = (parent, child, value) => {
|
||||
if (parent === "rate") {
|
||||
setComment((prevComment) => ({
|
||||
...prevComment,
|
||||
rate: prevComment.rate.map((item) =>
|
||||
item.name === child ? { ...item, progress: value } : item
|
||||
),
|
||||
}));
|
||||
} else {
|
||||
setComment((prevComment) => ({
|
||||
...prevComment,
|
||||
[parent]: {
|
||||
...prevComment[parent],
|
||||
[child]: value,
|
||||
},
|
||||
}));
|
||||
}
|
||||
};
|
||||
const averageRate =
|
||||
comment.rate.reduce((sum, item) => sum + item.progress, 0) /
|
||||
comment.rate.length /
|
||||
20;
|
||||
|
||||
const sendReq = () => {
|
||||
setLoading(true);
|
||||
request
|
||||
.postDoctorComment(comment.detail)
|
||||
.then((res) => {
|
||||
console.log(res);
|
||||
let newComment = comment.rate;
|
||||
newComment = {
|
||||
correct_diagnosis: newComment[1].progress,
|
||||
doctor_skill: newComment[4].progress,
|
||||
behavior_doctor: newComment[2].progress,
|
||||
office_cleaning: newComment[3].progress,
|
||||
time_in_office: newComment[0].progress,
|
||||
doctor: doctor?.id,
|
||||
rate: averageRate,
|
||||
};
|
||||
console.log(newComment);
|
||||
|
||||
request
|
||||
.postDoctorRate(newComment)
|
||||
.then((res) => {
|
||||
setLoading(false);
|
||||
setOpen(false);
|
||||
console.log(res);
|
||||
})
|
||||
.catch((err) => {
|
||||
setLoading(false);
|
||||
setOpen(false);
|
||||
console.log(err);
|
||||
});
|
||||
})
|
||||
.catch((err) => {
|
||||
setLoading(false);
|
||||
setOpen(false);
|
||||
console.log(err);
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -39,6 +109,7 @@ function ModalAnswer({ doctor }) {
|
||||
</div>
|
||||
<Rating
|
||||
className="!my-[24px]"
|
||||
value={averageRate}
|
||||
dir="ltr"
|
||||
sx={{
|
||||
"& .MuiSvgIcon-root": {
|
||||
@@ -48,8 +119,13 @@ function ModalAnswer({ doctor }) {
|
||||
}}
|
||||
/>
|
||||
<ul className="flex w-full lg:w-fit flex-col items-start justify-start gap-1.5">
|
||||
{doctor?.progress_detail?.map((item, idx) => (
|
||||
<ProgressChange data={item} key={idx} />
|
||||
{comment.rate?.map((item, idx) => (
|
||||
<ProgressChange
|
||||
key={idx}
|
||||
data={item}
|
||||
parent="rate"
|
||||
changeData={changeData}
|
||||
/>
|
||||
))}
|
||||
</ul>
|
||||
<div className="flex flex-col gap-[16px] justify-center items-start mt-[24px]">
|
||||
@@ -57,19 +133,20 @@ function ModalAnswer({ doctor }) {
|
||||
<Field
|
||||
type="number"
|
||||
multiline={true}
|
||||
handleChange={(_, val) => changeData("detail", "comment", val)}
|
||||
title="نظر خود را بنویسید..."
|
||||
/>
|
||||
<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"
|
||||
>
|
||||
دریافت نوبت
|
||||
<div className="w-[20px] h-[20px]">
|
||||
<ArrowLeftD />
|
||||
</div>
|
||||
</Button>
|
||||
</Link>
|
||||
<Button
|
||||
onClick={sendReq}
|
||||
loading={loading}
|
||||
variant="contained"
|
||||
className="!py-2.5 !mr-auto !px-4 gap-1 !text-[14px] !font-medium !mt-[32px] !shadownon"
|
||||
>
|
||||
ثبت نظر
|
||||
<div className="w-[20px] h-[20px]">
|
||||
<ArrowLeftD />
|
||||
</div>
|
||||
</Button>
|
||||
</div>
|
||||
</Box>
|
||||
</Modal>
|
||||
|
||||
@@ -5,7 +5,7 @@ import AboutDcotor from "./cards/AboutDcotor";
|
||||
import Comments from "./cards/comments";
|
||||
import Locations from "./cards/locations";
|
||||
|
||||
function DetailDoctor({ doctor }) {
|
||||
function DetailDoctor({ doctor, comments }) {
|
||||
return (
|
||||
<div className="w-full lg:w-[59%]">
|
||||
<div className="hidden lg:flex">
|
||||
@@ -15,7 +15,7 @@ function DetailDoctor({ doctor }) {
|
||||
<Link />
|
||||
<AboutDcotor doctor={doctor} />
|
||||
<Locations doctor={doctor} />
|
||||
<Comments doctor={doctor} />
|
||||
<Comments doctor={doctor} comments={comments} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2,9 +2,10 @@ import AppointmentList from "./appointmentList";
|
||||
import DetailDoctor from "./detailDoctor";
|
||||
import Share from "./detailDoctor/Share";
|
||||
import CustomLoading from "@/app/component/loading/Custom";
|
||||
import Poster from "./poster";
|
||||
|
||||
function DoctorPage({ doctor, doctors }) {
|
||||
function DoctorPage({ doctor, doctors, comments }) {
|
||||
console.log(comments);
|
||||
|
||||
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">
|
||||
@@ -24,7 +25,7 @@ function DoctorPage({ doctor, doctors }) {
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-start justify-center gap-6 mt-[30px]">
|
||||
<DetailDoctor doctor={doctor} />
|
||||
<DetailDoctor doctor={doctor} comments={comments} />
|
||||
<AppointmentList doctors={doctors} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -23,8 +23,6 @@ function DoctorsPage({ params, matchedCity, matchedState, list }) {
|
||||
const findItem = (id) => specialties.find((item) => item.id === id);
|
||||
const isParent = findItem(fieldId) && findItem(fieldId).parent;
|
||||
|
||||
const findSpecial = (id) => specialties.find((item) => item.id === id);
|
||||
|
||||
const [data, setData] = useState({
|
||||
category: isParent ? findItem(isParent) : findItem(fieldId),
|
||||
specialties: isParent && findItem(fieldId),
|
||||
|
||||
@@ -14,7 +14,7 @@ function ListDoctors({ loading, list }) {
|
||||
</ul>
|
||||
) : (
|
||||
<p className="text-center py-10 text-gray-500">
|
||||
هیچ دکتری وجود ندارد!
|
||||
دکتری برای نمایش وجود ندارد.
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
[
|
||||
{
|
||||
"name": "time_in_office",
|
||||
"label": "زمان انتظار در مطب",
|
||||
"progress": 70
|
||||
},
|
||||
{
|
||||
"name": "correct_diagnosis",
|
||||
"label": "تشخیص درست",
|
||||
"progress": 70
|
||||
},
|
||||
{
|
||||
"name": "behavior_doctor",
|
||||
"label": "برخورد مناسب پزشک",
|
||||
"progress": 70
|
||||
},
|
||||
{
|
||||
"name": "office_cleaning",
|
||||
"label": "نظافت مطب",
|
||||
"progress": 70
|
||||
},
|
||||
{
|
||||
"name": "doctor_skill",
|
||||
"label": "مهارت پزشک",
|
||||
"progress": 70
|
||||
}
|
||||
]
|
||||
@@ -76,4 +76,6 @@ export const request = {
|
||||
}),
|
||||
getDoctorServices: () =>
|
||||
api.get("api/v1/categorys/doctor_services", removeTokenHead),
|
||||
postDoctorComment: (data) => api.post("api/v1/clinicpro/comment", data),
|
||||
postDoctorRate: (data) => api.post("api/v1/clinicpro/rate", data)
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user