change format all file

This commit is contained in:
Ehsan
2025-05-18 01:18:35 +03:30
parent 4a57468e26
commit 254d5d4ebd
84 changed files with 721 additions and 651 deletions
+1 -3
View File
@@ -10,9 +10,7 @@ function SocialMedia({ loading }) {
<ul className="flex mt-0 sm:mt-[3px] md:mt-[6px] lg:mt-[8px] pb-[16px] sm:pb-[21px] md:pb-[27px] lg:pb-[32px] relative items-center justify-end gap-4">
{socials.map((item, idx) => (
<CircularLoading width={36} key={idx} height={36} loading={loading}>
<li
className="bg-[#EFEFEF] rounded-full hover-rotate-icon p-[9px]"
>
<li className="bg-[#EFEFEF] rounded-full hover-rotate-icon p-[9px]">
{item}
</li>
</CircularLoading>
+18 -25
View File
@@ -1,32 +1,25 @@
import Information from "./information";
import Location from "./location";
function Content({
doctor,
step,
setStep,
children,
isFirst,
disableSide,
}) {
return (
<div
className="flex flex-col lg:flex-row justify-center gap-[12px] sm:gap-[16px] md:gap-[20px] lg:gap-[24px] padding-responsive
function Content({ doctor, step, setStep, children, isFirst, disableSide }) {
return (
<div
className="flex flex-col lg:flex-row justify-center gap-[12px] sm:gap-[16px] md:gap-[20px] lg:gap-[24px] padding-responsive
items-stretch pt-[calc(12px_+_75px_+_32px)] sm:pt-[calc(21px_+_75px_+_45px)] md:pt-[calc(30px_+_75px_+_58px)] lg:pt-[calc(40px_+_75px_+_78px)]"
>
{isFirst ? (
<Location disableSide={disableSide} doctor={doctor} />
) : (
<Information
disableSide={disableSide}
doctor={doctor}
step={step}
setStep={setStep}
/>
)}
{children}
</div>
);
>
{isFirst ? (
<Location disableSide={disableSide} doctor={doctor} />
) : (
<Information
disableSide={disableSide}
doctor={doctor}
step={step}
setStep={setStep}
/>
)}
{children}
</div>
);
}
export default Content;
+3 -1
View File
@@ -19,7 +19,9 @@ function Information({ doctor, step, setStep, typePay, isPay, disableSide }) {
}
`}
>
<p className="text-[#3B3B3B] text-[14px] sm:text-[16px] md:text-[18px] lg:text-[20px] font-bold">جزئیات نوبت</p>
<p className="text-[#3B3B3B] text-[14px] sm:text-[16px] md:text-[18px] lg:text-[20px] font-bold">
جزئیات نوبت
</p>
<Head doctor={doctor} />
<Detail doctor={doctor} step={step} setStep={setStep} />
</div>
@@ -16,7 +16,7 @@ function Slider({ data, loading }) {
className="min-w-[90px] min-h-[90px] object-cover rounded-[8px] overflow-hidden"
/>
</CustomLoading>
) : undefined
) : undefined,
)}
</ul>
);
+1 -2
View File
@@ -1,4 +1,3 @@
import { Button, ButtonGroup, TextField } from "@mui/material";
import SearchD from "@/components/icons/SearchD";
import ModalSearchCity from "@/app/component/modalSearchCity";
@@ -28,7 +27,7 @@ function SearchBar({ selected, setSelected, state, handleSearch }) {
</ModalSearchCity>
<TextField
variant="standard"
onChange={e => handleSearch(e.target.value)}
onChange={(e) => handleSearch(e.target.value)}
InputProps={{
disableUnderline: true,
}}
+3 -4
View File
@@ -10,7 +10,7 @@ import HeadPageList from "@/app/component/head";
function ClinicsPage({ matchedCity, matchedState }) {
const [loading, setLoading] = useState(true);
const [filteredClinics, setFilteredClinics] = useState(clinics)
const [filteredClinics, setFilteredClinics] = useState(clinics);
const [selected, setSelected] = useState({
province: matchedState?.name || "",
@@ -23,10 +23,9 @@ function ClinicsPage({ matchedCity, matchedState }) {
}, 2000);
}, []);
const handleSearch = (value) => {
const searchOnName = searchOnList(clinics, value, 'title')
const searchOnLocation = searchOnList(searchOnName, selected.city, 'city')
const searchOnName = searchOnList(clinics, value, "title");
const searchOnLocation = searchOnList(searchOnName, selected.city, "city");
setFilteredClinics(searchOnLocation);
};
+3 -1
View File
@@ -16,7 +16,9 @@ function ItemClinic({ data, loading }) {
</CircularLoading>
<div className="flex flex-col items-start justify-center gap-2">
<TextLoading loading={loading} width={100} height={18}>
<h3 className="text-[#3B3B3B] text-[14px] font-bold">{data.title}</h3>
<h3 className="text-[#3B3B3B] text-[14px] font-bold">
{data.title}
</h3>
</TextLoading>
<TextLoading loading={loading} width={60} height={18}>
<p className="text-[#7E7E7E] text-[14px] font-normal">
+2 -1
View File
@@ -10,7 +10,8 @@ function ContentContact({ text, children, url, label }) {
{children}
</div>
<p className="text-[#FFF] text-[14px] md:text-[18px] sm:text-[16px] lg:text-[20px] font-normal">
{label}<span dir="ltr">{text}</span>
{label}
<span dir="ltr">{text}</span>
</p>
</li>
);
+4 -2
View File
@@ -6,10 +6,12 @@ function Call({ matchedCity, isDefault }) {
className={`lg:min-w-[calc(50%_+_70px)] bg-banner-about !bg-center !bg-no-repeat !bg-cover h-fit pt-[16px] sm:pt-[29px] md:pt-[42px] lg:pt-[55px]
bg-contact rounded-[8px] pb-[30px] sm:pb-[42px] md:pb-[55px]
overflow-hidden lg:pb-[171px] px-[16px] sm:px-[27px] md:px-[39px] lg:px-[48px]
${isDefault ? 'lg:pl-[18%]' : 'w-full'}`}
${isDefault ? "lg:pl-[18%]" : "w-full"}`}
>
<h1 className="text-[#FAFAFA] text-[20px] font-bold">تماس با ما</h1>
<h2 className="text-[#FAFAFA] leading-[26px] text-[14px] md:text-[16px] font-normal mt-6">{matchedCity.footerDescription}</h2>
<h2 className="text-[#FAFAFA] leading-[26px] text-[14px] md:text-[16px] font-normal mt-6">
{matchedCity.footerDescription}
</h2>
<Links matchedCity={matchedCity} />
</div>
);
+26 -22
View File
@@ -6,27 +6,31 @@ import WhatsappC from "../../icons/WhatsappC";
import ContentContact from "../ContentContact";
function Links({ matchedCity }) {
return (
<ul className="flex flex-col mt-[68px] justify-start items-start gap-[32px]">
<ContentContact url="tel:900300400" label='تلفن تماس: ' text={matchedCity.contactPhone}>
<CallC />
</ContentContact>
<ContentContact
url="https://wa.me/09124568794"
text={matchedCity.socialMedia.whatsapp}
label='واتساپ: '
>
<WhatsappC />
</ContentContact>
<ContentContact
url="mailto:batome@gmail.com"
text={matchedCity.email}
label='ایمیل: '
>
<EmailC />
</ContentContact>
</ul>
)
return (
<ul className="flex flex-col mt-[68px] justify-start items-start gap-[32px]">
<ContentContact
url="tel:900300400"
label="تلفن تماس: "
text={matchedCity.contactPhone}
>
<CallC />
</ContentContact>
<ContentContact
url="https://wa.me/09124568794"
text={matchedCity.socialMedia.whatsapp}
label="واتساپ: "
>
<WhatsappC />
</ContentContact>
<ContentContact
url="mailto:batome@gmail.com"
text={matchedCity.email}
label="ایمیل: "
>
<EmailC />
</ContentContact>
</ul>
);
}
export default Links
export default Links;
+1 -3
View File
@@ -9,9 +9,7 @@ function ContactUsPage() {
return (
<div className="w-full pt-[24px] sm:pt-[56px] md:pt-[88px] lg:pt-[120px] mt-[56px] padding-responsive flex flex-col lg:flex-row items-center justify-between h-fit">
<Call matchedCity={matchedCity} isDefault={isDefault} />
{matchedCity?.id === "63" && (
<Connect />
)}
{matchedCity?.id === "63" && <Connect />}
</div>
);
}
+25 -25
View File
@@ -7,32 +7,32 @@ import DashboardPage from "@/components/dashboard";
import UserAccountPage from "@/components/dashboard/userAccount/UserAccount";
function Content({ matchedCity }) {
const [value, setValue] = useState(0);
const [isOpenSide, setIsOpenSide] = useState(false);
const [isTurnsDetails, setIsTurnsDetails] = useState(false);
const [value, setValue] = useState(0);
const [isOpenSide, setIsOpenSide] = useState(false);
const [isTurnsDetails, setIsTurnsDetails] = useState(false);
return (
<DashboardPage
value={value}
setValue={setValue}
user={userData.data}
isOpenSide={isOpenSide}
matchedCity={matchedCity}
setIsOpenSide={setIsOpenSide}
isTurnsDetails={isTurnsDetails}
setIsTurnsDetails={setIsTurnsDetails}
>
<UserAccountPage
value={value}
setValue={setValue}
user={userData.data}
isOpenSide={isOpenSide}
setIsOpenSide={setIsOpenSide}
isTurnsDetails={isTurnsDetails}
setIsTurnsDetails={setIsTurnsDetails}
/>
</DashboardPage>
);
return (
<DashboardPage
value={value}
setValue={setValue}
user={userData.data}
isOpenSide={isOpenSide}
matchedCity={matchedCity}
setIsOpenSide={setIsOpenSide}
isTurnsDetails={isTurnsDetails}
setIsTurnsDetails={setIsTurnsDetails}
>
<UserAccountPage
value={value}
setValue={setValue}
user={userData.data}
isOpenSide={isOpenSide}
setIsOpenSide={setIsOpenSide}
isTurnsDetails={isTurnsDetails}
setIsTurnsDetails={setIsTurnsDetails}
/>
</DashboardPage>
);
}
export default Content;
+1 -1
View File
@@ -9,7 +9,7 @@ function DashboardPage({
setValue,
isOpenSide,
setIsOpenSide,
matchedCity
matchedCity,
}) {
return (
<Layout
@@ -24,8 +24,8 @@ function Card({ data, loading }) {
data.status === "success"
? "bg-[#E8FADD] text-[#75E22E]"
: data.status === "pending"
? "bg-[#FFF3DD] text-[#FDBA35]"
: "bg-[#FFE3E2] text-[#FF5450]"
? "bg-[#FFF3DD] text-[#FDBA35]"
: "bg-[#FFE3E2] text-[#FF5450]"
}
`}
variant="text"
@@ -33,8 +33,8 @@ function Card({ data, loading }) {
{data.status === "success"
? "پرداخت شده"
: data.status === "pending"
? "در انتظار"
: "پرداخت نشده"}
? "در انتظار"
: "پرداخت نشده"}
</div>
</TextLoading>
</div>
@@ -92,8 +92,8 @@ function List({ user, loading }) {
row.status === "success"
? "bg-[#E8FADD] text-[#75E22E]"
: row.status === "pending"
? "bg-[#FFF3DD] text-[#FDBA35]"
: "bg-[#FFE3E2] text-[#FF5450]"
? "bg-[#FFF3DD] text-[#FDBA35]"
: "bg-[#FFE3E2] text-[#FF5450]"
}
`}
variant="text"
@@ -101,8 +101,8 @@ function List({ user, loading }) {
{row.status === "success"
? "پرداخت شده"
: row.status === "pending"
? "در انتظار"
: "پرداخت نشده"}
? "در انتظار"
: "پرداخت نشده"}
</div>
</CustomLoading>
</TableCell>
@@ -21,10 +21,11 @@ function AboutDcotor({ doctor, loading }) {
text-[#616161] text-[14px] font-normal overflow-hidden relative
md:max-h-fit after:absolute after:right-0 after:bottom-0 leading-[28px] sm:leading-[30px] md:leading-[32px] lg:leading-[33px] after:h-[80px]
after:shadow-xl after:w-full transition-all duration-500 md:after:!bg-[linear-gradient(transparent,transparent)]
${isMore
? "after:bg-transparent max-h-screen"
: "after:bg-[linear-gradient(transparent,#FAFAFA)] max-h-[200px]"
}
${
isMore
? "after:bg-transparent max-h-screen"
: "after:bg-[linear-gradient(transparent,#FAFAFA)] max-h-[200px]"
}
`}
>
{doctor.detail}
@@ -27,7 +27,9 @@ function ProgressAll({ doctor, loading }) {
<br />
رضایت کاربران
</p>
<p className="text-[#3B3B3B]">{numberToArStyle(doctor.total_user_satisfaction)}%</p>
<p className="text-[#3B3B3B]">
{numberToArStyle(doctor.total_user_satisfaction)}%
</p>
</div>
</CircularLoading>
</div>
@@ -54,8 +54,9 @@ function Chart({ doctor, loading }) {
</div>
<div className="flex flex-wrap items-center justify-center gap-[50px]">
<ul
className={`flex w-full flex-col items-start justify-start gap-1.5 ${loading ? "lg:w-full" : "lg:w-fit"
}`}
className={`flex w-full flex-col items-start justify-start gap-1.5 ${
loading ? "lg:w-full" : "lg:w-fit"
}`}
>
{doctor.progress_detail.map((item, idx) => (
<TextLoading width="full" key={idx} height={20} loading={loading}>
+8 -5
View File
@@ -18,14 +18,17 @@ function DoctorsPage({ params, matchedCity, matchedState }) {
province: matchedState?.name || params?.province,
city: matchedCity?.name || params?.city,
});
const findItem = (name, value) => specialties.find(item => item[name] === value)
const itemCategory = findItem('id', params.category);
const itemSpecialties = findItem('id', params.specialties);
const findItem = (name, value) =>
specialties.find((item) => item[name] === value);
const itemCategory = findItem("id", params.category);
const itemSpecialties = findItem("id", params.specialties);
const [data, setData] = useState({
category: itemCategory || "",
specialties: itemSpecialties ? { ...itemSpecialties, label: itemSpecialties.name } : "",
turn: params && params.hasOwnProperty('turn') ? JSON.parse(params.turn) : 1,
specialties: itemSpecialties
? { ...itemSpecialties, label: itemSpecialties.name }
: "",
turn: params && params.hasOwnProperty("turn") ? JSON.parse(params.turn) : 1,
gender: params.gender || "هر دو",
degree: params.degree || "متخصص",
});
+11 -12
View File
@@ -6,7 +6,6 @@ import { filterList } from "@/helper";
const group1 = ["خانم", "آقا", "هر دو"];
const group2 = ["فوق تخصص", "دکترای تخصصی", "متخصص", "دکتری"];
function Content({ data, setData }) {
const router = useRouter();
const { parentList, childrenList } = filterList(data);
@@ -15,21 +14,21 @@ function Content({ data, setData }) {
const current = new URLSearchParams(window.location.search);
current.set(name, value.id || value);
if (removeSpecialties) {
current.delete('specialties')
};
current.delete("specialties");
}
const queryString = current.toString();
router.push(`/doctors?${queryString}`)
}
router.push(`/doctors?${queryString}`);
};
const changeData = (value, name, removeSpecialties) => {
changeUrl(value, name, removeSpecialties);
const newData = data;
newData[name] = value;
if (removeSpecialties) {
newData.specialties = ''
};
newData.specialties = "";
}
setData(newData);
}
};
return (
<div className="mt-[50px] px-[0px] md:px-[19px] lg:px-[38px] mb-[32px]">
@@ -59,7 +58,7 @@ function Content({ data, setData }) {
value={data.gender}
text="جنسیت پزشک"
group={group1}
name='gender'
name="gender"
/>
<span className="block mt-[16px] mb-[24px] w-full h-px bg-[#EFEFEF]"></span>
<RadioContent
@@ -67,7 +66,7 @@ function Content({ data, setData }) {
value={data.degree}
text="درجه علمی"
group={group2}
name='degree'
name="degree"
/>
<span className="block mt-[16px] mb-[24px] w-full h-px bg-[#EFEFEF]"></span>
<div className="flex items-center justify-start gap-[12px]">
@@ -76,7 +75,7 @@ function Content({ data, setData }) {
<Switch
checked={data.turn}
onChange={(event) => {
changeData(event.target.checked ? 1 : 0, "turn")
changeData(event.target.checked ? 1 : 0, "turn");
}}
/>
}
@@ -86,7 +85,7 @@ function Content({ data, setData }) {
fontSize: "16px",
fontWeight: 500,
},
marginLeft: '0 !important',
marginLeft: "0 !important",
}}
label="فقط پزشکان دارای نوبت"
labelPlacement="start"
+8 -2
View File
@@ -16,7 +16,13 @@ function FilterModal({ data, setData, children }) {
const handleClose = () => setOpen(false);
const deleteData = () => {
clearFilterParams(router, ['turn', 'specialties', 'degree', 'category', 'gender'])
clearFilterParams(router, [
"turn",
"specialties",
"degree",
"category",
"gender",
]);
setData({
category: "",
specialties: "",
@@ -25,7 +31,7 @@ function FilterModal({ data, setData, children }) {
degree: "متخصص",
});
handleClose();
}
};
return (
<>
+1 -1
View File
@@ -31,7 +31,7 @@ function SearchBar({ data, setData, params }) {
</FilterModal>
<TextField
variant="standard"
defaultValue={params.search || ''}
defaultValue={params.search || ""}
InputProps={{
disableUnderline: true,
}}
+19 -10
View File
@@ -29,13 +29,17 @@ function SelectSort() {
</SvgIcon>
{value ? (
<ul className="flex items-center justify-start gap-1">
{Array(sort).fill({}).map((_, idx) => (
<li key={idx}>
<StarDI />
</li>
))}
{Array(sort)
.fill({})
.map((_, idx) => (
<li key={idx}>
<StarDI />
</li>
))}
</ul>
) : "مرتب سازی"}
) : (
"مرتب سازی"
)}
</div>
);
}}
@@ -60,10 +64,15 @@ function SelectSort() {
name={item.label}
className="!flex !flex-col !items-start !w-full hover:!bg-transparent"
>
<div value={item.id} className="!p-2 !mr-2 !w-[calc(100%_-_16px)] flex items-center justify-start">
{Array(item.label).fill({}).map((_, idx) => (
<StarDI key={idx} />
))}
<div
value={item.id}
className="!p-2 !mr-2 !w-[calc(100%_-_16px)] flex items-center justify-start"
>
{Array(item.label)
.fill({})
.map((_, idx) => (
<StarDI key={idx} />
))}
</div>
</MenuItem>
))}
+10 -9
View File
@@ -5,10 +5,9 @@ import specialties from "@/data/specialties.json";
import Link from "next/link";
function FrequentSearches() {
const childrenList = specialties.filter(item => item.parent);
const childrenList = specialties.filter((item) => item.parent);
console.log(childrenList);
return (
<div className="flex items-center justify-center gap-[8px] sm:gap-[10px] md:gap-[13px] lg:gap-[16px] w-full">
<p className="text-[#3B3B3B] text-[14px] md:text-[16px] font-normal text-nowrap">
@@ -17,13 +16,15 @@ function FrequentSearches() {
<div className="overflow-auto hidden-scroll flex justify-start max-w-[620px]">
<ul className="flex items-center justify-start gap-[14px] pl-[14px]">
{childrenList.map((item, idx) => (
<Link href={{
pathname: "/doctors",
query: {
category: item.parent,
specialties: item.id,
},
}}>
<Link
href={{
pathname: "/doctors",
query: {
category: item.parent,
specialties: item.id,
},
}}
>
<li key={idx}>
<Button
variant="contained"
+19 -19
View File
@@ -3,27 +3,27 @@ import AText from "../icons/AText";
import BText from "../icons/BText";
function TextHeader() {
const { matchedCity } = getStateInfo();
const { matchedCity } = getStateInfo();
return (
<div className="z-[50]">
<h1 className="text-[#F17732] text-center font-kalame text-[20px] sm:text-[24px] md:text-[28px] lg:text-[32px] font-bold">
با {matchedCity?.site_name}
</h1>
<h2
className="text-[#525252] text-center mt-2.5 font-kalame text-[16px] sm:text-[25px] md:text-[31px] lg:text-[36px]
return (
<div className="z-[50]">
<h1 className="text-[#F17732] text-center font-kalame text-[20px] sm:text-[24px] md:text-[28px] lg:text-[32px] font-bold">
با {matchedCity?.site_name}
</h1>
<h2
className="text-[#525252] text-center mt-2.5 font-kalame text-[16px] sm:text-[25px] md:text-[31px] lg:text-[36px]
font-bold flex items-center gap-0.5 sm:gap-1 md:gap-2"
>
<div className="max-w-[18px] sm:max-w-[22px]">
<BText />
</div>
{matchedCity?.slogan}
<div className="max-w-[18px] sm:max-w-[22px]">
<AText />
</div>
</h2>
>
<div className="max-w-[18px] sm:max-w-[22px]">
<BText />
</div>
)
{matchedCity?.slogan}
<div className="max-w-[18px] sm:max-w-[22px]">
<AText />
</div>
</h2>
</div>
);
}
export default TextHeader
export default TextHeader;
+76 -76
View File
@@ -1,4 +1,4 @@
"use client"
"use client";
import { useState } from "react";
@@ -10,86 +10,86 @@ import Link from "next/link";
import SearchD from "@/components/icons/SearchD";
function Fields({ city, state }) {
const [open, setOpen] = useState(false);
const [data, setData] = useState({
province: state?.name || '',
city: city?.name || '',
});
const [open, setOpen] = useState(false);
const [data, setData] = useState({
province: state?.name || "",
city: city?.name || "",
});
return (
<>
<ModalSearchCity
open={open}
state={state}
selected={data}
setOpen={setOpen}
setSelected={setData}
>
<ButtonFilter setOpen={setOpen} selected={data} />
</ModalSearchCity>
<span className="black w-px bg-[#EFEFEF]"></span>
<TextField
variant="standard"
onChange={e => setData({ ...data, search: e.target.value })}
InputProps={{
disableUnderline: true,
}}
sx={{
display: "flex",
flexDirection: "column",
justifyContent: "center",
"& .MuiInput-root": {
padding: "0",
borderBottom: "none",
},
"& .MuiInputBase-input": {
color: "#6C757D",
},
"& .MuiInputBase-input": {
color: "#6C757D",
fontSize: {
xs: "10px !important",
sm: "12px !important",
md: "14px !important",
lg: "16px !important",
},
}
}}
placeholder="جستجوی نام پزشک، تخصص، بیماری ..."
dir="rtl"
className={`!shadow-none !w-full lg:!w-[524px] bg-[#FAFAFA] !text-[14px] md:!text-[16px] !rounded-0 !font-normal !text-[#6C757D]`}
/>
<Link
href={{
pathname: "/doctors",
query: {
province: data.province,
city: data.city,
search: data.search
},
}}
>
<Button className="!hidden lg:!flex !rounded-[4px] !h-[40px] sm:!h-[42px] md:!h-[45px] lg:!h-[48px] !gap-2.5 !min-w-[114px]">
<div className="min-w-[20px] min-h-[20px]">
<Search />
</div>
<p>جستجو</p>
</Button>
<Button
className="!flex lg:!hidden !rounded-[4px]
return (
<>
<ModalSearchCity
open={open}
state={state}
selected={data}
setOpen={setOpen}
setSelected={setData}
>
<ButtonFilter setOpen={setOpen} selected={data} />
</ModalSearchCity>
<span className="black w-px bg-[#EFEFEF]"></span>
<TextField
variant="standard"
onChange={(e) => setData({ ...data, search: e.target.value })}
InputProps={{
disableUnderline: true,
}}
sx={{
display: "flex",
flexDirection: "column",
justifyContent: "center",
"& .MuiInput-root": {
padding: "0",
borderBottom: "none",
},
"& .MuiInputBase-input": {
color: "#6C757D",
},
"& .MuiInputBase-input": {
color: "#6C757D",
fontSize: {
xs: "10px !important",
sm: "12px !important",
md: "14px !important",
lg: "16px !important",
},
},
}}
placeholder="جستجوی نام پزشک، تخصص، بیماری ..."
dir="rtl"
className={`!shadow-none !w-full lg:!w-[524px] bg-[#FAFAFA] !text-[14px] md:!text-[16px] !rounded-0 !font-normal !text-[#6C757D]`}
/>
<Link
href={{
pathname: "/doctors",
query: {
province: data.province,
city: data.city,
search: data.search,
},
}}
>
<Button className="!hidden lg:!flex !rounded-[4px] !h-[40px] sm:!h-[42px] md:!h-[45px] lg:!h-[48px] !gap-2.5 !min-w-[114px]">
<div className="min-w-[20px] min-h-[20px]">
<Search />
</div>
<p>جستجو</p>
</Button>
<Button
className="!flex lg:!hidden !rounded-[4px]
!w-[40px] sm:!w-[42px] md:!w-[45px] lg:!w-[48px]
!h-[40px] sm:!h-[42px] md:!h-[45px] lg:!h-[48px]
!min-w-[40px] sm:!min-w-[42px] md:!min-w-[45px] lg:!min-w-[48px]
!min-h-[40px] sm:!min-h-[42px] md:!min-h-[45px] lg:!min-h-[48px]
!gap-2.5 !p-2.5"
>
<div className="w-[24px] h-[24px] min-w-[24px] min-h-[24px]">
<SearchD />
</div>
</Button>
</Link>
</>
)
>
<div className="w-[24px] h-[24px] min-w-[24px] min-h-[24px]">
<SearchD />
</div>
</Button>
</Link>
</>
);
}
export default Fields
export default Fields;
+1 -1
View File
@@ -3,7 +3,7 @@ import Fields from "./Fields";
import { getStateInfo } from "@/lib/getStateInfo";
function SearchBar() {
const { matchedCity, matchedState } = getStateInfo()
const { matchedCity, matchedState } = getStateInfo();
return (
<ButtonGroup
+10 -6
View File
@@ -32,16 +32,16 @@ function ModalSearchCity() {
// Load states and cities from JSON files
useEffect(() => {
// Format states data to match the structure expected by AutoCompleteSelect
const formattedStates = statesData.map(state => ({
const formattedStates = statesData.map((state) => ({
label: state.name,
id: state.id
id: state.id,
}));
// Format cities data
const formattedCities = citiesData.map(city => ({
const formattedCities = citiesData.map((city) => ({
label: city.name,
id: city.id,
province_id: city.province_id
province_id: city.province_id,
}));
setStates(formattedStates);
@@ -51,10 +51,14 @@ function ModalSearchCity() {
// Filter cities when state is selected
useEffect(() => {
if (selected.first) {
const selectedState = states.find(state => state.label === selected.first);
const selectedState = states.find(
(state) => state.label === selected.first,
);
if (selectedState) {
const stateId = selectedState.id;
const filteredCities = cities.filter(city => city.province_id === stateId);
const filteredCities = cities.filter(
(city) => city.province_id === stateId,
);
setFilteredCities(filteredCities);
}
} else {
+1 -3
View File
@@ -14,9 +14,7 @@ function UserEdit({ active }) {
strokeWidth="1.5"
strokeLinecap="round"
strokeLinejoin="round"
className={
active ? "stroke-[#FAFAFA] delay-500" : ""
}
className={active ? "stroke-[#FAFAFA] delay-500" : ""}
/>
<path
d="M32.5166 26.2334L26.6165 32.1334C26.3832 32.3668 26.1666 32.8 26.1166 33.1167L25.7999 35.3667C25.6832 36.1833 26.2499 36.75 27.0666 36.6334L29.3165 36.3167C29.6332 36.2667 30.0832 36.05 30.2999 35.8167L36.1999 29.9167C37.2165 28.9001 37.6999 27.7167 36.1999 26.2167C34.7165 24.7333 33.5333 25.2167 32.5166 26.2334Z"
+21 -23
View File
@@ -3,31 +3,29 @@ import Footer from "./footer";
import Header from "./header";
function StLayout({ children, name }) {
const { matchedCity } = getStateInfo();
const { matchedCity } = getStateInfo();
return (
<div>
<main className="w-full min-h-screen">
<header className="w-full sticky bg-[#FFF] !z-[70] shadow-[0px_1px_24.8px_0px_rgba(204,_204,_204,_0.18)] mt-[12px] sm:mt-[21px] md:mt-[30px] lg:mt-[40px] top-0 right-1/2">
<div className="w-full padding-responsive">
<Header matchedCity={matchedCity} name={name} />
</div>
</header>
<section
className="opacity-page -mt-[calc(48px_+_12px)] sm:-mt-[calc(56px_+_21px)] md:-mt-[calc(64px_+_30px)] lg:-mt-[calc(80px_+_40px)]"
>
{children}
</section>
</main>
<footer className="bg-[#F5F5F5] mt-[100px] bg-banner-footer !bg-center !bg-no-repeat !bg-cover">
<div className="pt-[44px] bg-[rgba(255,255,255,0.45)]">
<div className="padding-responsive">
<Footer matchedCity={matchedCity} />
</div>
</div>
</footer>
return (
<div>
<main className="w-full min-h-screen">
<header className="w-full sticky bg-[#FFF] !z-[70] shadow-[0px_1px_24.8px_0px_rgba(204,_204,_204,_0.18)] mt-[12px] sm:mt-[21px] md:mt-[30px] lg:mt-[40px] top-0 right-1/2">
<div className="w-full padding-responsive">
<Header matchedCity={matchedCity} name={name} />
</div>
</header>
<section className="opacity-page -mt-[calc(48px_+_12px)] sm:-mt-[calc(56px_+_21px)] md:-mt-[calc(64px_+_30px)] lg:-mt-[calc(80px_+_40px)]">
{children}
</section>
</main>
<footer className="bg-[#F5F5F5] mt-[100px] bg-banner-footer !bg-center !bg-no-repeat !bg-cover">
<div className="pt-[44px] bg-[rgba(255,255,255,0.45)]">
<div className="padding-responsive">
<Footer matchedCity={matchedCity} />
</div>
</div>
);
</footer>
</div>
);
}
export default StLayout;
+18 -11
View File
@@ -24,16 +24,20 @@ const head = [
];
function Footer({ matchedCity }) {
const socialMedias = [{
icon: <Instagram />,
name: 'instagram'
}, {
icon: <Telegram />,
name: 'telegram'
}, {
icon: <Whatsapp />,
name: 'whatsapp'
}];
const socialMedias = [
{
icon: <Instagram />,
name: "instagram",
},
{
icon: <Telegram />,
name: "telegram",
},
{
icon: <Whatsapp />,
name: "whatsapp",
},
];
const [openMenu, setOpenMenu] = useState({
right: false,
left: false,
@@ -106,7 +110,10 @@ function Footer({ matchedCity }) {
key={idx}
className="p-2.5 bg-[#EAECFA] hover-rotate-icon cursor-pointer rounded-full w-fit"
>
<Link href={matchedCity?.socialMedia[item.name] || '/'} className="min-h-fit">
<Link
href={matchedCity?.socialMedia[item.name] || "/"}
className="min-h-fit"
>
{item.icon}
</Link>
</li>
+33 -37
View File
@@ -11,48 +11,44 @@ import UserLogin from "@/components/icons/UserLogin";
import { useState } from "react";
function Content({ matchedCity, name }) {
const [isActive, setIsActive] = useState(false);
const [isActive, setIsActive] = useState(false);
return (
<div
className={`
return (
<div
className={`
px-[8px] sm:px-[16px] md:px-[24px] lg:px-[32px] py-[4px] sm:py-[8px] md:py-[12px] lg:py-[16px]
flex transition-all duration-500 overflow-hidden justify-between items-center flex-nowrap
${isActive ? "!pr-0" : "!px-4"}
`}
>
<div>
<BgGray isActive={isActive} setIsActive={setIsActive} />
<Col name={name} isActive={isActive} />
<div className="relative flex flex-row-reverse gap-2">
<Logo matchedCity={matchedCity} />
<div className="flex lg:hidden z-20">
<ButtonMenu isActive={isActive} setIsActive={setIsActive} />
<Logo isAbsolute={true} matchedCity={matchedCity} />
</div>
</div>
</div>
<Row name={name} />
<Link href="/login">
<Button
className="!hidden lg:!flex"
variant="outlined"
color="primary"
>
ورود | ثبت نام
</Button>
<Button
className={`!flex lg:!hidden !p-2 !rounded-full transition-all duration-500 !bg-[#EFEFEF]`}
variant="text"
color="primary"
>
<div className="flex lg:hidden">
<UserLogin />
</div>
</Button>
</Link>
>
<div>
<BgGray isActive={isActive} setIsActive={setIsActive} />
<Col name={name} isActive={isActive} />
<div className="relative flex flex-row-reverse gap-2">
<Logo matchedCity={matchedCity} />
<div className="flex lg:hidden z-20">
<ButtonMenu isActive={isActive} setIsActive={setIsActive} />
<Logo isAbsolute={true} matchedCity={matchedCity} />
</div>
</div>
)
</div>
<Row name={name} />
<Link href="/login">
<Button className="!hidden lg:!flex" variant="outlined" color="primary">
ورود | ثبت نام
</Button>
<Button
className={`!flex lg:!hidden !p-2 !rounded-full transition-all duration-500 !bg-[#EFEFEF]`}
variant="text"
color="primary"
>
<div className="flex lg:hidden">
<UserLogin />
</div>
</Button>
</Link>
</div>
);
}
export default Content
export default Content;
+1 -5
View File
@@ -1,13 +1,9 @@
import Content from "./Content";
function Header({ matchedCity, name }) {
return (
<div className="bg-[#FFF] rounded-lg w-full mx-auto">
<Content
matchedCity={matchedCity}
name={name}
/>
<Content matchedCity={matchedCity} name={name} />
</div>
);
}
+1 -4
View File
@@ -9,10 +9,7 @@ function Row({ name }) {
<Link
href={nav.link}
className={`
${nav.link === name
? "!text-[#526CAC]"
: "text-[#525252]"
}
${nav.link === name ? "!text-[#526CAC]" : "text-[#525252]"}
text-[16px] font-medium
`}
>
+1 -1
View File
@@ -23,7 +23,7 @@ function Col({ isActive, name }) {
${
isActiveURL(
nav.link.replace("/", ""),
name
name,
)
? "!text-[#526CAC] !bg-[rgba(199,_206,_244,_0.30)]"
: "!text-[#525252]"
+5 -4
View File
@@ -14,7 +14,7 @@ function Layout({
user,
value,
setValue,
matchedCity
matchedCity,
}) {
return (
<div>
@@ -30,9 +30,10 @@ function Layout({
<section
className={`
opacity-page -mt-[calc(48px_+_12px)] sm:-mt-[calc(56px_+_21px)] md:-mt-[calc(64px_+_30px)] lg:-mt-[calc(80px_+_40px)]
${isSidebar &&
"padding-responsive min-h-screen flex items-stretch justify-center gap-[12px] lg:gap-[24px] pt-[76px] sm:pt-[109px] mt:pt-[142px] lg:pt-[176px]"
}
${
isSidebar &&
"padding-responsive min-h-screen flex items-stretch justify-center gap-[12px] lg:gap-[24px] pt-[76px] sm:pt-[109px] mt:pt-[142px] lg:pt-[176px]"
}
`}
>
{isSidebar && (
+1 -1
View File
@@ -1,4 +1,4 @@
"use client"
"use client";
import CardD from "@/components/icons/CardD";
import LogoutD from "@/components/icons/LogoutD";
+1 -1
View File
@@ -6,7 +6,7 @@ import { removeToken } from "@/utils";
function ModalLogout({ open, handleClose }) {
const logout = () => {
removeToken();
window.location.pathname = '/login'
window.location.pathname = "/login";
handleClose();
};
+44 -43
View File
@@ -9,53 +9,54 @@ import { usePathname } from "next/navigation";
import BgGray from "@/components/layoutPanel/sidebar/BgGray";
function Content({ children }) {
const pathname = usePathname();
const [active, setActive] = useState(false);
const [open, setOpen] = useState(true);
const [loading, setLoading] = useState(true);
const pathname = usePathname();
const [active, setActive] = useState(false);
const [open, setOpen] = useState(true);
const [loading, setLoading] = useState(true);
useEffect(() => {
setTimeout(() => {
setLoading(false);
}, 2000);
}, []);
useEffect(() => {
setTimeout(() => {
setLoading(false);
}, 2000);
}, []);
return (
<div className="flex min-h-screen dark:bg-[#1F1D2B]">
<Sidebar
open={open}
active={active}
setOpen={setOpen}
setActive={setActive}
/>
<BgGray isActive={active} setIsActive={setActive} />
<main
className={`
return (
<div className="flex min-h-screen dark:bg-[#1F1D2B]">
<Sidebar
open={open}
active={active}
setOpen={setOpen}
setActive={setActive}
/>
<BgGray isActive={active} setIsActive={setActive} />
<main
className={`
w-full transition-all duration-500 dark:bg-[#1F1D2B]
${pathname.includes("dashboard")
? open
? "md:min-w-[calc(100%_-_243px)] md:w-[calc(100%_-_243px)] xl:min-w-[calc(100%_-_243px_-_332px)] xl:w-[calc(100%_-_243px_-_332px)]"
: "md:min-w-[calc(100%_-_96px)] md:w-[calc(100%_-_96px)] xl:min-w-[calc(100%_-_96px_-_332px)] xl:w-[calc(100%_-_96px_-_332px)]"
: open
? "md:w-[calc(100%-243px)]"
: "md:w-[calc(100%-96px)]"
}
${
pathname.includes("dashboard")
? open
? "md:min-w-[calc(100%_-_243px)] md:w-[calc(100%_-_243px)] xl:min-w-[calc(100%_-_243px_-_332px)] xl:w-[calc(100%_-_243px_-_332px)]"
: "md:min-w-[calc(100%_-_96px)] md:w-[calc(100%_-_96px)] xl:min-w-[calc(100%_-_96px_-_332px)] xl:w-[calc(100%_-_96px_-_332px)]"
: open
? "md:w-[calc(100%-243px)]"
: "md:w-[calc(100%-96px)]"
}
`}
>
<Header
data={Information}
setActive={setActive}
disableProfile={pathname.includes("dashboard")}
/>
<section className="my-[24px] opacity-element mx-[16px] bg-[#FAFAFA] dark:bg-[#1F1D2B]">
{children}
</section>
</main>
{pathname.includes("dashboard") && (
<UserDetail data={Information} loading={loading} />
)}
</div>
);
>
<Header
data={Information}
setActive={setActive}
disableProfile={pathname.includes("dashboard")}
/>
<section className="my-[24px] opacity-element mx-[16px] bg-[#FAFAFA] dark:bg-[#1F1D2B]">
{children}
</section>
</main>
{pathname.includes("dashboard") && (
<UserDetail data={Information} loading={loading} />
)}
</div>
);
}
export default Content;
+4 -1
View File
@@ -16,7 +16,10 @@ function Table({ data, loading }) {
centerTable={centerTable}
>
{data.list_of_doctors_appointments.map((row, idx) => (
<TableRow key={idx} className="!border-0 !border-b !border-[#DBDBDB] dark:!border-transparent">
<TableRow
key={idx}
className="!border-0 !border-b !border-[#DBDBDB] dark:!border-transparent"
>
<TableCell
className="!pr-[18px] dark:!border-transparent !text-[#616161] dark:!text-[#A1A1A1] !text-[16px] !font-medium !text-nowrap"
align="center"
+2 -4
View File
@@ -2,11 +2,9 @@ import RegisterPage from "@/components/register";
import { getStateInfo } from "@/lib/getStateInfo";
function ContentLogin() {
const { matchedCity } = getStateInfo();
const { matchedCity } = getStateInfo();
return (
<RegisterPage matchedCity={matchedCity} />
);
return <RegisterPage matchedCity={matchedCity} />;
}
export default ContentLogin;
+13 -13
View File
@@ -6,20 +6,20 @@ import LogInPage from "@/components/register/LogInPage";
import { useState } from "react";
function ContentVerify() {
const [isSendMsg, setIsSendMsg] = useState(false);
const [isSendMsg, setIsSendMsg] = useState(false);
return (
<RegisterPage>
{isSendMsg ? (
<SetCodePage
setIsSendMsg={setIsSendMsg}
link={`/account/${localStorage.getItem("doctor-id")}`}
/>
) : (
<LogInPage setIsSendMsg={setIsSendMsg} />
)}
</RegisterPage>
);
return (
<RegisterPage>
{isSendMsg ? (
<SetCodePage
setIsSendMsg={setIsSendMsg}
link={`/account/${localStorage.getItem("doctor-id")}`}
/>
) : (
<LogInPage setIsSendMsg={setIsSendMsg} />
)}
</RegisterPage>
);
}
export default ContentVerify;
+35 -33
View File
@@ -4,41 +4,43 @@ import Link from "next/link";
const about = ["سوالات متداول", "تماس با ما", "درباره ما"];
function LayoutRegister({ children, matchedCity }) {
return (
<div
className="flex padding-responsive items-center justify-center pt-[32px]
return (
<div
className="flex padding-responsive items-center justify-center pt-[32px]
overflow-auto flex-col h-screen w-full bg-banner-stroke !bg-bottom !bg-no-repeat !bg-cover
!pb-[60px] md:!pb-[60px]"
>
<Link href="/">
<div className="flex items-center justify-center gap-[5px] sm:mt-0">
<Image
src="/assets/images/logo.png"
width={40}
height={40}
alt="logo"
/>
<p className="text-[#5559CE] text-[20px] font-bold">{matchedCity?.site_name || "نوبت ۷۲۴"}</p>
</div>
</Link>
{children}
<div className="fixed bottom-0 left-0 bg-[#FAFAFA] w-full pb-[10px] md:pb-[14px] px-[18px] sm:px-[67px] md:px[117px] lg:px-[166px]">
<div className="bg-border-t-gradient-sign h-px w-full"></div>
<div className="flex items-center justify-center gap-[32px] sm:gap-[40px] md:gap-[48px] lg:gap-[56px] mt-[10px] md:mt-[14px]">
{about.map((item, idx) => (
<Link href="/" key={idx}>
<p
className="text-[#494CB3] text-[14px] md:text-[16px] font-normal"
key={idx}
>
{item}
</p>
</Link>
))}
</div>
</div>
>
<Link href="/">
<div className="flex items-center justify-center gap-[5px] sm:mt-0">
<Image
src="/assets/images/logo.png"
width={40}
height={40}
alt="logo"
/>
<p className="text-[#5559CE] text-[20px] font-bold">
{matchedCity?.site_name || "نوبت ۷۲۴"}
</p>
</div>
)
</Link>
{children}
<div className="fixed bottom-0 left-0 bg-[#FAFAFA] w-full pb-[10px] md:pb-[14px] px-[18px] sm:px-[67px] md:px[117px] lg:px-[166px]">
<div className="bg-border-t-gradient-sign h-px w-full"></div>
<div className="flex items-center justify-center gap-[32px] sm:gap-[40px] md:gap-[48px] lg:gap-[56px] mt-[10px] md:mt-[14px]">
{about.map((item, idx) => (
<Link href="/" key={idx}>
<p
className="text-[#494CB3] text-[14px] md:text-[16px] font-normal"
key={idx}
>
{item}
</p>
</Link>
))}
</div>
</div>
</div>
);
}
export default LayoutRegister
export default LayoutRegister;
+19 -12
View File
@@ -6,7 +6,7 @@ import { useState } from "react";
function LogInPage({ setIsSendMsg, setStep, matchedCity }) {
const [num, setNum] = useState("");
const [error, setError] = useState({ valid: true, text: '' });
const [error, setError] = useState({ valid: true, text: "" });
const handleChange = (val) => {
const formatted = formatPhoneNumber(val);
@@ -34,28 +34,35 @@ function LogInPage({ setIsSendMsg, setStep, matchedCity }) {
error={!error.valid}
spaceNull={true}
inputProps={{
startAdornment:
startAdornment: (
<InputAdornment
className="!ml-4"
position="start"
sx={{
'.MuiTypography-root': {
lineHeight: '0 !important',
".MuiTypography-root": {
lineHeight: "0 !important",
},
".muirtl-1qj5e5k-MuiTypography-root": {
color: "#000000de !important",
},
'.muirtl-1qj5e5k-MuiTypography-root': {
color: '#000000de !important'
}
}}
>09</InputAdornment>,
>
09
</InputAdornment>
),
}}
title="شماره همراه"
updateState={handleChange}
/>
<p className={`
<p
className={`
text-[#d32f2f] text-[14px] mt-2 min-h-[21px] transition-all duration-1000 ease-in-out
transform
${error.valid ? 'opacity-0 -translate-y-1' : 'opacity-100 translate-y-0'}
`}>{error.text}</p>
${error.valid ? "opacity-0 -translate-y-1" : "opacity-100 translate-y-0"}
`}
>
{error.text}
</p>
</div>
<Button
fullWidth
@@ -77,7 +84,7 @@ function LogInPage({ setIsSendMsg, setStep, matchedCity }) {
<Link href="/">
<span className="text-[#F17732] underline">قوانین استفاده</span>
</Link>{" "}
از {matchedCity?.site_name || 'نوبت 724'} را می پذیرم.
از {matchedCity?.site_name || "نوبت 724"} را می پذیرم.
</p>
</div>
);
+5 -1
View File
@@ -13,7 +13,11 @@ function RegisterPage({ matchedCity }) {
{isSendMsg ? (
<SetCodePage setIsSendMsg={setIsSendMsg} setStep={false} link="/" />
) : (
<LogInPage matchedCity={matchedCity} setStep={false} setIsSendMsg={setIsSendMsg} />
<LogInPage
matchedCity={matchedCity}
setStep={false}
setIsSendMsg={setIsSendMsg}
/>
)}
</LayoutRegister>
);
+1 -1
View File
@@ -11,7 +11,7 @@ function SmSearch({ placeholder, handleSearch }) {
>
<TextField
variant="standard"
onChange={e => handleSearch(e.target.value)}
onChange={(e) => handleSearch(e.target.value)}
InputProps={{
disableUnderline: true,
}}
+4 -6
View File
@@ -8,10 +8,11 @@ import specialtiesData from "@/data/specialties.json";
import { searchOnList } from "@/helper";
function SpecialtiesPage() {
const [filteredSpecialties, setFilteredSpecialties] = useState(specialtiesData);
const [filteredSpecialties, setFilteredSpecialties] =
useState(specialtiesData);
const handleSearch = (value) =>
setFilteredSpecialties(searchOnList(specialtiesData, value, 'name'));
setFilteredSpecialties(searchOnList(specialtiesData, value, "name"));
return (
<div className="">
@@ -19,10 +20,7 @@ function SpecialtiesPage() {
title="تخصص مورد نظر شما چیست؟"
detail="تخصص مورد نظرتان را جستجو کرده و یا از لیست زیر انتخاب نمایید:"
>
<SmSearch
placeholder="جستجوی تخصص"
handleSearch={handleSearch}
/>
<SmSearch placeholder="جستجوی تخصص" handleSearch={handleSearch} />
</HeadPageList>
<List specialties={filteredSpecialties} />
</div>
@@ -14,7 +14,9 @@ function ItemSpecialties({ data }) {
rounded-lg bg-[#FFF] shadow-[0px_1px_24.8px_0px_rgba(204,_204,_204,_0.18)]
hover:bg-[#5559CE] transition-all text-item-head-white duration-500 cursor-pointer hover-mode-item-speciality"
>
<h2 className="text-[#3B3B3B] item-head text-[16px] font-bold text-center">{data.name}</h2>
<h2 className="text-[#3B3B3B] item-head text-[16px] font-bold text-center">
{data.name}
</h2>
<p className="text-[#7E7E7E] text-[14px] font-medium">
{data.number_of_doctors} پزشک
</p>