add prettier formatter to all file

This commit is contained in:
Ehsan
2024-09-25 11:03:44 +03:30
parent fa38ee2b21
commit eda896e917
410 changed files with 47636 additions and 43842 deletions
+16 -13
View File
@@ -1,16 +1,19 @@
function AnimationTextHead({ name, text, children }) {
return (
<div className='flex justify-center items-start relative w-fit'>
<div className='overflow-hidden mb-[4px] md:mb-[5px] lg:mb-[6px]'>
<p
data-aos={name}
className='text-[#3B3B3B] text-nowrap overflow-hidden text-[14px] sm:text-[16px] md:text-[18px] lg:text-[20px] font-bold'>{text}</p>
</div>
<div className="absolute bottom-0 right-1/2 translate-x-1/2 w-full flex justify-center">
{children}
</div>
</div>
)
return (
<div className="flex justify-center items-start relative w-fit">
<div className="overflow-hidden mb-[4px] md:mb-[5px] lg:mb-[6px]">
<p
data-aos={name}
className="text-[#3B3B3B] text-nowrap overflow-hidden text-[14px] sm:text-[16px] md:text-[18px] lg:text-[20px] font-bold"
>
{text}
</p>
</div>
<div className="absolute bottom-0 right-1/2 translate-x-1/2 w-full flex justify-center">
{children}
</div>
</div>
);
}
export default AnimationTextHead
export default AnimationTextHead;
+40 -33
View File
@@ -1,39 +1,46 @@
import { Table, TableBody, TableCell, TableContainer, TableHead, TableRow } from '@mui/material'
import {
Table,
TableBody,
TableCell,
TableContainer,
TableHead,
TableRow,
} from "@mui/material";
function CustomTable({ tableHead, zeroRadius, centerTable, children }) {
return (
<TableContainer
className='!shadow-none table-shadow-none !overflow-auto !border !border-solid !border-[#DBDBDB]'
sx={{
'&.MuiTableContainer-root': {
borderRadius: zeroRadius && '0 !important'
}
}}
>
<Table className='!rounded-0 !shadow-none !overflow-hidden'>
<TableHead>
<TableRow
className='!bg-[#EFEFEF]'
>
{tableHead.map((item, idx) => (
<TableCell
key={idx}
className={`
return (
<TableContainer
className="!shadow-none table-shadow-none !overflow-auto !border !border-solid !border-[#DBDBDB]"
sx={{
"&.MuiTableContainer-root": {
borderRadius: zeroRadius && "0 !important",
},
}}
>
<Table className="!rounded-0 !shadow-none !overflow-hidden">
<TableHead>
<TableRow className="!bg-[#EFEFEF]">
{tableHead.map((item, idx) => (
<TableCell
key={idx}
className={`
!text-[#616161] !text-[14px] !font-normal !py-[10px] !px-[18px]
${centerTable.includes(idx) ? '!text-center' : '!text-start'}
${
centerTable.includes(idx)
? "!text-center"
: "!text-start"
}
`}
>
{item}
</TableCell>
))}
</TableRow>
</TableHead>
<TableBody>
{children}
</TableBody>
</Table>
</TableContainer>
)
>
{item}
</TableCell>
))}
</TableRow>
</TableHead>
<TableBody>{children}</TableBody>
</Table>
</TableContainer>
);
}
export default CustomTable
export default CustomTable;
+60 -52
View File
@@ -1,55 +1,63 @@
import EditGrayA from "@/components/icons/EditGrayA"
import EditOrangeA from "@/components/icons/EditOrangeA"
import { Button, TextField } from "@mui/material"
import EditGrayA from "@/components/icons/EditGrayA";
import EditOrangeA from "@/components/icons/EditOrangeA";
import { Button, TextField } from "@mui/material";
function EditField({ changeData, multiline, icon, placeholder, data, name, iconGray, isTransparent }) {
return (
<div className="relative w-full">
<TextField
value={data?.value}
rows={multiline}
multiline={multiline}
disabled={!data?.isEdit}
placeholder={placeholder || ''}
type='text'
className={`!w-full res-field-account ${isTransparent ? '!bg-transparent lg:!bg-[#FFF]' : '!bg-[#FFF]'}`}
onChange={e => {
changeData(e.target.value, 'value', name)
}}
sx={{
'& .MuiFormLabel-root': {
top: '-4px !important'
},
'& .MuiInputBase-input': { padding: '12.5px 14px' },
'& .MuiOutlinedInput-notchedOutline': { border: '1px solid #D7D7D7 !important' },
'& .MuiInputBase-root': {
padding: '0 !important',
borderRadius: '8px !important'
},
'.Mui-focused': {
'& .MuiOutlinedInput-notchedOutline': {
border: '1px solid #5559CE !important',
transition: '0.5s all'
}
}
}}
/>
<Button
className={`!absolute !left-[8px] !-translate-y-1/2 !min-w-fit !p-1
${multiline ? '!top-[24px]' : '!top-1/2'}`}
onClick={() => {
changeData(!data.isEdit, 'isEdit', name)
}}
>
{icon ? icon :
iconGray ? (
<EditGrayA />
) : (
<EditOrangeA />
)}
</Button>
</div>
)
function EditField({
changeData,
multiline,
icon,
placeholder,
data,
name,
iconGray,
isTransparent,
}) {
return (
<div className="relative w-full">
<TextField
value={data?.value}
rows={multiline}
multiline={multiline}
disabled={!data?.isEdit}
placeholder={placeholder || ""}
type="text"
className={`!w-full res-field-account ${
isTransparent ? "!bg-transparent lg:!bg-[#FFF]" : "!bg-[#FFF]"
}`}
onChange={(e) => {
changeData(e.target.value, "value", name);
}}
sx={{
"& .MuiFormLabel-root": {
top: "-4px !important",
},
"& .MuiInputBase-input": { padding: "12.5px 14px" },
"& .MuiOutlinedInput-notchedOutline": {
border: "1px solid #D7D7D7 !important",
},
"& .MuiInputBase-root": {
padding: "0 !important",
borderRadius: "8px !important",
},
".Mui-focused": {
"& .MuiOutlinedInput-notchedOutline": {
border: "1px solid #5559CE !important",
transition: "0.5s all",
},
},
}}
/>
<Button
className={`!absolute !left-[8px] !-translate-y-1/2 !min-w-fit !p-1
${multiline ? "!top-[24px]" : "!top-1/2"}`}
onClick={() => {
changeData(!data.isEdit, "isEdit", name);
}}
>
{icon ? icon : iconGray ? <EditGrayA /> : <EditOrangeA />}
</Button>
</div>
);
}
export default EditField
export default EditField;
+28 -26
View File
@@ -1,30 +1,32 @@
import { TextField } from "@mui/material"
import { TextField } from "@mui/material";
function Field({ title, type, multiline, isPlaceHolder }) {
return (
<TextField
placeholder={isPlaceHolder && title}
label={!isPlaceHolder ? title : ''}
type={type || 'text'}
multiline={!!multiline}
rows={!!multiline ? 4 : 1}
className="!w-full !mx-auto !bg-[#FFF]"
sx={{
'& .MuiFormLabel-root': {
top: '-4px !important'
},
'& .MuiInputBase-input': { padding: '12.5px 14px' },
'& .MuiInputBase-root': { borderRadius: '6px !important' },
'& .MuiOutlinedInput-notchedOutline': { border: '1px solid #E9ECEF !important' },
".Mui-focused": {
'& .MuiOutlinedInput-notchedOutline': {
border: '1px solid #5559CE !important',
transition: '0.5s all'
}
}
}}
/>
)
return (
<TextField
placeholder={isPlaceHolder && title}
label={!isPlaceHolder ? title : ""}
type={type || "text"}
multiline={!!multiline}
rows={!!multiline ? 4 : 1}
className="!w-full !mx-auto !bg-[#FFF]"
sx={{
"& .MuiFormLabel-root": {
top: "-4px !important",
},
"& .MuiInputBase-input": { padding: "12.5px 14px" },
"& .MuiInputBase-root": { borderRadius: "6px !important" },
"& .MuiOutlinedInput-notchedOutline": {
border: "1px solid #E9ECEF !important",
},
".Mui-focused": {
"& .MuiOutlinedInput-notchedOutline": {
border: "1px solid #5559CE !important",
transition: "0.5s all",
},
},
}}
/>
);
}
export default Field
export default Field;
+38 -38
View File
@@ -1,42 +1,42 @@
import EditGrayA from "@/components/icons/EditGrayA"
import EditOrangeA from "@/components/icons/EditOrangeA"
import { Button, TextField } from "@mui/material"
import EditGrayA from "@/components/icons/EditGrayA";
import EditOrangeA from "@/components/icons/EditOrangeA";
import { Button, TextField } from "@mui/material";
function FieldIcon({ changeData, icon, placeholder, name }) {
return (
<div className="relative w-full">
<TextField
placeholder={placeholder || ''}
type='text'
className='!w-full'
onChange={e => {
changeData(e.target.value, name)
}}
sx={{
'& .MuiFormLabel-root': {
top: '-4px !important'
},
'& .MuiInputBase-input': { padding: '12.5px 14px' },
'& .MuiOutlinedInput-notchedOutline': { border: '1px solid #D7D7D7 !important' },
'& .MuiInputBase-root': {
padding: '0 !important',
borderRadius: '8px !important'
},
'.Mui-focused': {
'& .MuiOutlinedInput-notchedOutline': {
border: '1px solid #5559CE !important',
transition: '0.5s all'
}
}
}}
/>
<Button
className='!absolute !top-1/2 !left-[8px] !-translate-y-1/2 !min-w-fit !p-1'
>
{icon}
</Button>
</div>
)
return (
<div className="relative w-full">
<TextField
placeholder={placeholder || ""}
type="text"
className="!w-full"
onChange={(e) => {
changeData(e.target.value, name);
}}
sx={{
"& .MuiFormLabel-root": {
top: "-4px !important",
},
"& .MuiInputBase-input": { padding: "12.5px 14px" },
"& .MuiOutlinedInput-notchedOutline": {
border: "1px solid #D7D7D7 !important",
},
"& .MuiInputBase-root": {
padding: "0 !important",
borderRadius: "8px !important",
},
".Mui-focused": {
"& .MuiOutlinedInput-notchedOutline": {
border: "1px solid #5559CE !important",
transition: "0.5s all",
},
},
}}
/>
<Button className="!absolute !top-1/2 !left-[8px] !-translate-y-1/2 !min-w-fit !p-1">
{icon}
</Button>
</div>
);
}
export default FieldIcon
export default FieldIcon;
+78 -67
View File
@@ -12,75 +12,86 @@ import TextLoading from "./loading/Text";
import CircularLoading from "./loading/Circular";
function ItemDoctor({ doctor, loading }) {
return (
<li className="p-4 relative rounded-lg bg-[#FFF] border border-[#EFEFEF]">
{/* Detail Doctor */}
<div className="flex items-center justify-start gap-2.5">
<CircularLoading loading={loading} width={66} height={66}>
<Image
width={72}
height={72}
src={doctor.img}
alt="image-doctor"
className="w-[64px] md:w-[68px] lg:w-[72px] h-[64px] md:h-[68px] lg:h-[72px]"
/>
</CircularLoading>
<div className="flex flex-col items-start justify-center gap-2">
<TextLoading width={90} height={15} loading={loading}>
<p className="text-[#3B3B3B] text-[14px] font-bold">{doctor.name}</p>
</TextLoading>
<TextLoading width={120} height={15} loading={loading}>
<p className="text-[#616161] text-[14px] font-normal">تخصص: {doctor.expertise}</p>
</TextLoading>
<CustomLoading width={100} height={25} loading={loading}>
<div className="flex rounded items-center justify-start gap-2">
<div className="p-1 bg-[#F8F8FF] flex items-center rounded-[4px] gap-0.5">
<LikeD />
<p className="text-[#616161] text-[12px] font-normal">{doctor.satisfaction}%</p>
</div>
<div className="p-1 bg-[#F8F8FF] flex items-center rounded-[4px] gap-0.5">
<PointD />
<p className="text-[#616161] text-[12px] font-normal">{doctor.point}</p>
</div>
</div>
</CustomLoading>
</div>
return (
<li className="p-4 relative rounded-lg bg-[#FFF] border border-[#EFEFEF]">
{/* Detail Doctor */}
<div className="flex items-center justify-start gap-2.5">
<CircularLoading loading={loading} width={66} height={66}>
<Image
width={72}
height={72}
src={doctor.img}
alt="image-doctor"
className="w-[64px] md:w-[68px] lg:w-[72px] h-[64px] md:h-[68px] lg:h-[72px]"
/>
</CircularLoading>
<div className="flex flex-col items-start justify-center gap-2">
<TextLoading width={90} height={15} loading={loading}>
<p className="text-[#3B3B3B] text-[14px] font-bold">
{doctor.name}
</p>
</TextLoading>
<TextLoading width={120} height={15} loading={loading}>
<p className="text-[#616161] text-[14px] font-normal">
تخصص: {doctor.expertise}
</p>
</TextLoading>
<CustomLoading width={100} height={25} loading={loading}>
<div className="flex rounded items-center justify-start gap-2">
<div className="p-1 bg-[#F8F8FF] flex items-center rounded-[4px] gap-0.5">
<LikeD />
<p className="text-[#616161] text-[12px] font-normal">
{doctor.satisfaction}%
</p>
</div>
<div className="p-1 bg-[#F8F8FF] flex items-center rounded-[4px] gap-0.5">
<PointD />
<p className="text-[#616161] text-[12px] font-normal">
{doctor.point}
</p>
</div>
</div>
</CustomLoading>
</div>
</div>
{/* Hours of work */}
<div className="flex my-4 items-center justify-start gap-0.5">
<ClockD />
<TextLoading width={150} height={15} loading={loading}>
<p className="text-[#7E7E7E] text-[12px] font-normal">ساعت کاری: {doctor.hours_of_work}</p>
</TextLoading>
</div>
<CustomLoading loading={loading} width={150} height={20}>
<p
className={`text-[12px] font-medium rounded w-fit p-1.5 ml-[52px]
${doctor.free_turn ?
'bg-[rgba(5,_186,_88,_0.04)] text-[#05BA58]' :
'bg-[rgba(211,_47,_47,_0.04)] text-[#D32F2F]'
}`}
>{doctor.free_turn ?
`اولین نوبت آزاد: ${doctor.free_turn}` :
'نوبت ندارد'
}</p>
</CustomLoading>
{/* Arrow */}
<Link href={`/doctor/${doctor.id}`}>
<Button
variant="contained"
className={`!p-[14px] !absolute !left-4 !bottom-4 !rounded-full !w-fit
${!doctor.free_turn || loading &&
'!bg-[#D7D7D7]'}
{/* Hours of work */}
<div className="flex my-4 items-center justify-start gap-0.5">
<ClockD />
<TextLoading width={150} height={15} loading={loading}>
<p className="text-[#7E7E7E] text-[12px] font-normal">
ساعت کاری: {doctor.hours_of_work}
</p>
</TextLoading>
</div>
<CustomLoading loading={loading} width={150} height={20}>
<p
className={`text-[12px] font-medium rounded w-fit p-1.5 ml-[52px]
${
doctor.free_turn
? "bg-[rgba(5,_186,_88,_0.04)] text-[#05BA58]"
: "bg-[rgba(211,_47,_47,_0.04)] text-[#D32F2F]"
}`}
>
{doctor.free_turn
? `اولین نوبت آزاد: ${doctor.free_turn}`
: "نوبت ندارد"}
</p>
</CustomLoading>
{/* Arrow */}
<Link href={`/doctor/${doctor.id}`}>
<Button
variant="contained"
className={`!p-[14px] !absolute !left-4 !bottom-4 !rounded-full !w-fit
${!doctor.free_turn || (loading && "!bg-[#D7D7D7]")}
`}
disabled={!doctor.free_turn || loading}
>
<ArrowLeftD />
</Button>
</Link>
</li>
)
disabled={!doctor.free_turn || loading}
>
<ArrowLeftD />
</Button>
</Link>
</li>
);
}
export default ItemDoctor
export default ItemDoctor;
+20 -18
View File
@@ -1,22 +1,24 @@
import Image from 'next/image'
import Link from 'next/link'
import React from 'react'
import Image from "next/image";
import Link from "next/link";
import React from "react";
function Logo({ isAbsolute }) {
return (
<Link href='/' className={isAbsolute ? 'absolute right-[32px] top-0' : ''}>
<div className="flex items-center justify-start gap-[5px]">
<Image
className='w-[20px] h-[20px] sm:w-[23px] sm:h-[23px] md:w-[26px] md:h-[26px] lg:w-[30px] lg:h-[30px]'
src='/assets/images/logo.png'
width={30}
height={30}
alt="logo"
/>
<p className="text-[#526CAC] text-[14px] lg:text-[16px] font-bold font-kalame">نوبت ۷۲۴</p>
</div>
</Link>
)
return (
<Link href="/" className={isAbsolute ? "absolute right-[32px] top-0" : ""}>
<div className="flex items-center justify-start gap-[5px]">
<Image
className="w-[20px] h-[20px] sm:w-[23px] sm:h-[23px] md:w-[26px] md:h-[26px] lg:w-[30px] lg:h-[30px]"
src="/assets/images/logo.png"
width={30}
height={30}
alt="logo"
/>
<p className="text-[#526CAC] text-[14px] lg:text-[16px] font-bold font-kalame">
نوبت ۷۲۴
</p>
</div>
</Link>
);
}
export default Logo
export default Logo;
+25 -20
View File
@@ -1,26 +1,31 @@
function Pageguide({ list }) {
return (
<ul className='flex items-center justify-start gap-1'>
{list.map((item, idx) => (
<li
key={idx}
className="flex items-center justify-start gap-1"
>
<p
className={`text-[16px] font-normal
${list.length > idx + 1 ? 'text-[#9B9B9B]' : 'text-[#525252]'}
return (
<ul className="flex items-center justify-start gap-1">
{list.map((item, idx) => (
<li key={idx} className="flex items-center justify-start gap-1">
<p
className={`text-[16px] font-normal
${
list.length > idx + 1
? "text-[#9B9B9B]"
: "text-[#525252]"
}
`}
>{item}</p>
<span
className={`
>
{item}
</p>
<span
className={`
text-[#9B9B9B] text-[16px] font-normal
${list.length > idx + 1 ? 'flex' : 'hidden'}
${list.length > idx + 1 ? "flex" : "hidden"}
`}
>{'>'}</span>
</li>
))}
</ul>
)
>
{">"}
</span>
</li>
))}
</ul>
);
}
export default Pageguide
export default Pageguide;
+23 -22
View File
@@ -1,26 +1,27 @@
import { Pagination as PaginationMUI } from '@mui/material'
import { Pagination as PaginationMUI } from "@mui/material";
function Pagination() {
return (
<PaginationMUI
// count={doctors.length / 12} org
count={20} // test
color='primary'
sx={{
'& .mui-8q7g72-MuiButtonBase-root-MuiPaginationItem-root': {
color: '#616161',
fontSize: '16px',
fontWeight: '500'
},
'& .mui-8q7g72-MuiButtonBase-root-MuiPaginationItem-root.Mui-selected': {
color: '#F8F8FF'
},
'& .MuiSvgIcon-root': {
rotate: '180deg !important'
}
}}
/>
)
return (
<PaginationMUI
// count={doctors.length / 12} org
count={20} // test
color="primary"
sx={{
"& .mui-8q7g72-MuiButtonBase-root-MuiPaginationItem-root": {
color: "#616161",
fontSize: "16px",
fontWeight: "500",
},
"& .mui-8q7g72-MuiButtonBase-root-MuiPaginationItem-root.Mui-selected":
{
color: "#F8F8FF",
},
"& .MuiSvgIcon-root": {
rotate: "180deg !important",
},
}}
/>
);
}
export default Pagination
export default Pagination;
+24 -20
View File
@@ -1,24 +1,28 @@
import { numberToArStyle } from "@/helper"
import { LinearProgress } from "@mui/material"
import { numberToArStyle } from "@/helper";
import { LinearProgress } from "@mui/material";
function ProgressDetail({ data }) {
return (
<li className="flex items-center justify-start gap-2 w-full">
<p className="text-[#525252] text-[14px] font-normal w-[118px]">{data.label}</p>
<LinearProgress
value={data.progress}
variant="determinate"
className="!w-full lg:!w-[265px] !rounded-[10px] !bg-[#D7D7D7] !h-[11px]"
sx={{
'& .MuiLinearProgress-bar': {
background: '#05BA58',
borderRadius: '10px'
}
}}
/>
<p className="text-[#525252] text-[20px] font-medium">{numberToArStyle(data.progress)}%</p>
</li>
)
return (
<li className="flex items-center justify-start gap-2 w-full">
<p className="text-[#525252] text-[14px] font-normal w-[118px]">
{data.label}
</p>
<LinearProgress
value={data.progress}
variant="determinate"
className="!w-full lg:!w-[265px] !rounded-[10px] !bg-[#D7D7D7] !h-[11px]"
sx={{
"& .MuiLinearProgress-bar": {
background: "#05BA58",
borderRadius: "10px",
},
}}
/>
<p className="text-[#525252] text-[20px] font-medium">
{numberToArStyle(data.progress)}%
</p>
</li>
);
}
export default ProgressDetail
export default ProgressDetail;
+35 -36
View File
@@ -1,41 +1,40 @@
import { Slider } from "@mui/material"
import { useState } from "react"
import { Slider } from "@mui/material";
import { useState } from "react";
function ProgressChange({ data }) {
const [value, setValue] = useState(70);
const [value, setValue] = useState(70)
return (
<li className="flex items-center justify-start gap-3 w-full">
<p className="text-[#525252] text-[14px] font-normal w-[118px]">{data.label}</p>
<Slider
defaultValue={value}
className="!w-full lg:!w-[265px] !rounded-[10px] !h-[11px]"
onChange={e => setValue(e.target.value)}
sx={{
'& .MuiSlider-rail': {
background: '#E8E8E8',
opacity: '100'
},
'& .MuiSlider-track': {
background: '#05BA58',
border: 'none'
},
'& .MuiSlider-thumb': {
marginRight: '-21px',
background: '#EBEBEB',
border: '1px solid #05BA58 !important'
},
'& .MuiSlider-thumb.Mui-focusVisible, .MuiSlider-thumb:hover': {
boxShadow: 'none'
},
}}
/>
<p className="text-[#525252] text-[20px] font-medium w-[30px]">
{value}
</p>
</li>
)
return (
<li className="flex items-center justify-start gap-3 w-full">
<p className="text-[#525252] text-[14px] font-normal w-[118px]">
{data.label}
</p>
<Slider
defaultValue={value}
className="!w-full lg:!w-[265px] !rounded-[10px] !h-[11px]"
onChange={(e) => setValue(e.target.value)}
sx={{
"& .MuiSlider-rail": {
background: "#E8E8E8",
opacity: "100",
},
"& .MuiSlider-track": {
background: "#05BA58",
border: "none",
},
"& .MuiSlider-thumb": {
marginRight: "-21px",
background: "#EBEBEB",
border: "1px solid #05BA58 !important",
},
"& .MuiSlider-thumb.Mui-focusVisible, .MuiSlider-thumb:hover": {
boxShadow: "none",
},
}}
/>
<p className="text-[#525252] text-[20px] font-medium w-[30px]">{value}</p>
</li>
);
}
export default ProgressChange
export default ProgressChange;
+35 -37
View File
@@ -1,41 +1,39 @@
import { Box, Tab, Tabs as TabsMUI } from '@mui/material';
import { Box, Tab, Tabs as TabsMUI } from "@mui/material";
function a11yProps(index) {
return {
id: `simple-tab-${index}`,
'aria-controls': `simple-tabpanel-${index}`,
};
};
function Tabs({ value, handleChange, listTab, isSm, style }) {
return (
<Box
className="!border-none !w-full"
>
<TabsMUI
value={value}
onChange={handleChange}
sx={{
...style,
'.MuiTabs-fixed': {
overflow: 'auto !important'
},
}}
>
{listTab.map((item, idx) => (
<Tab
key={idx}
label={item}
{...a11yProps(idx)}
className={`
text-[#495057] !p-1 !text-[14px] md:!text-[16px] !font-bold
${isSm ? '!w-1/2 !m-0' : '!mr-2'}
`}
/>
))}
</TabsMUI>
</Box>
)
return {
id: `simple-tab-${index}`,
"aria-controls": `simple-tabpanel-${index}`,
};
}
export default Tabs
function Tabs({ value, handleChange, listTab, isSm, style }) {
return (
<Box className="!border-none !w-full">
<TabsMUI
value={value}
onChange={handleChange}
sx={{
...style,
".MuiTabs-fixed": {
overflow: "auto !important",
},
}}
>
{listTab.map((item, idx) => (
<Tab
key={idx}
label={item}
{...a11yProps(idx)}
className={`
text-[#495057] !p-1 !text-[14px] md:!text-[16px] !font-bold
${isSm ? "!w-1/2 !m-0" : "!mr-2"}
`}
/>
))}
</TabsMUI>
</Box>
);
}
export default Tabs;
+56 -58
View File
@@ -1,65 +1,63 @@
// app/ThemeRegistry.tsx
'use client';
import createCache from '@emotion/cache';
import { prefixer } from 'stylis';
import rtlPlugin from 'stylis-plugin-rtl';
import { useServerInsertedHTML } from 'next/navigation';
import { CacheProvider, ThemeProvider } from '@emotion/react';
import React from 'react';
import theme from '../theme/theme';
"use client";
import createCache from "@emotion/cache";
import { prefixer } from "stylis";
import rtlPlugin from "stylis-plugin-rtl";
import { useServerInsertedHTML } from "next/navigation";
import { CacheProvider, ThemeProvider } from "@emotion/react";
import React from "react";
import theme from "../theme/theme";
// This implementation is from emotion-js
// https://github.com/emotion-js/emotion/issues/2928#issuecomment-1319747902
export default function ThemeRegistry({
children
}) {
const options = {
key: 'muirtl',
stylisPlugins: [prefixer, rtlPlugin],
export default function ThemeRegistry({ children }) {
const options = {
key: "muirtl",
stylisPlugins: [prefixer, rtlPlugin],
};
const [{ cache, flush }] = React.useState(() => {
const cache = createCache(options);
cache.compat = true;
const prevInsert = cache.insert;
let inserted = [];
cache.insert = (...args) => {
const serialized = args[1];
if (cache.inserted[serialized.name] === undefined) {
inserted.push(serialized.name);
}
return prevInsert(...args);
};
const flush = () => {
const prevInserted = inserted;
inserted = [];
return prevInserted;
};
return { cache, flush };
});
useServerInsertedHTML(() => {
const names = flush();
if (names.length === 0) {
return null;
}
let styles = "";
for (const name of names) {
styles += cache.inserted[name];
}
const [{ cache, flush }] = React.useState(() => {
const cache = createCache(options);
cache.compat = true;
const prevInsert = cache.insert;
let inserted = [];
cache.insert = (...args) => {
const serialized = args[1];
if (cache.inserted[serialized.name] === undefined) {
inserted.push(serialized.name);
}
return prevInsert(...args);
};
const flush = () => {
const prevInserted = inserted;
inserted = [];
return prevInserted;
};
return { cache, flush };
});
useServerInsertedHTML(() => {
const names = flush();
if (names.length === 0) {
return null;
}
let styles = '';
for (const name of names) {
styles += cache.inserted[name];
}
return (
<style
key={cache.key}
data-emotion={`${cache.key} ${names.join(' ')}`}
dangerouslySetInnerHTML={{
__html: styles,
}}
/>
);
});
return (
<CacheProvider value={cache}>
<ThemeProvider theme={theme}>{children}</ThemeProvider>
</CacheProvider>
<style
key={cache.key}
data-emotion={`${cache.key} ${names.join(" ")}`}
dangerouslySetInnerHTML={{
__html: styles,
}}
/>
);
}
});
return (
<CacheProvider value={cache}>
<ThemeProvider theme={theme}>{children}</ThemeProvider>
</CacheProvider>
);
}
+73 -62
View File
@@ -1,73 +1,84 @@
import { useState } from "react";
import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs";
import { LocalizationProvider, TimePicker } from "@mui/x-date-pickers"
import { LocalizationProvider, TimePicker } from "@mui/x-date-pickers";
function TimePickerField({ dataChange, disable, setData, timeStart, data }) {
const [value, setValue] = useState("00:00");
const [value, setValue] = useState('00:00');
return (
<div className="w-full relative">
<LocalizationProvider dateAdapter={AdapterDayjs}>
<TimePicker
ampm={false}
disabled={disable}
format="hh:mm"
className="!w-full"
shouldDisableTime={(timeValue, clockType) => {
if (clockType === "hours") {
const { idx, is_morgen } = dataChange;
const value =
data[idx][is_morgen ? "morning_time" : "evening_time"][0];
const hourSelected = value ? +value.split(":")[0] : false;
return (
<div className="w-full relative">
<LocalizationProvider dateAdapter={AdapterDayjs}>
<TimePicker
ampm={false}
disabled={disable}
format="hh:mm"
className="!w-full"
shouldDisableTime={(timeValue, clockType) => {
if (clockType === 'hours') {
const { idx, is_morgen } = dataChange;
const value = data[idx][is_morgen ? 'morning_time' : 'evening_time'][0];
const hourSelected = value ? +value.split(':')[0] : false
const disableMinHour =
timeStart || !value ? false : hourSelected + 1 > timeValue.$H;
return dataChange.is_morgen
? !(16 > timeValue.$H && timeValue.$H > 5 && !disableMinHour)
: !(24 > timeValue.$H && timeValue.$H > 11 && !disableMinHour);
}
}}
views={["hours", "minutes"]}
placeholder="انتخاب کنید..."
onChange={(e) => {
const hours = e.$H;
const minute = e.$m;
const handleTwoLength = (value) =>
String(value).length === 1 ? `0${value}` : value;
const newValue = `${handleTwoLength(hours)}:${handleTwoLength(
minute
)}`;
const disableMinHour = timeStart || !value ? false :
(hourSelected + 1 > timeValue.$H)
return dataChange.is_morgen ?
!(16 > timeValue.$H && timeValue.$H > 5 && !disableMinHour) :
!(24 > timeValue.$H && timeValue.$H > 11 && !disableMinHour)
const newData = data;
const { idx, is_morgen } = dataChange;
newData[idx][is_morgen ? "morning_time" : "evening_time"][
timeStart ? 0 : 1
] = newValue;
}
}}
views={['hours', 'minutes']}
placeholder="انتخاب کنید..."
onChange={e => {
const hours = e.$H;
const minute = e.$m;
const handleTwoLength = value => String(value).length === 1 ? `0${value}` : value
const newValue = `${handleTwoLength(hours)}:${handleTwoLength(minute)}`;
const newData = data;
const { idx, is_morgen } = dataChange;
newData[idx][is_morgen ? 'morning_time' : 'evening_time'][timeStart ? 0 : 1] = newValue;
setValue(newValue);
}}
sx={{
'& .MuiFormLabel-root': {
top: '-4px !important'
},
'& .MuiInputBase-input': { padding: '12.5px 14px' },
'& .MuiOutlinedInput-notchedOutline': { border: '1px solid #D7D7D7 !important' },
'& .MuiInputBase-root': {
borderRadius: '8px !important'
},
'.Mui-focused': {
'& .MuiOutlinedInput-notchedOutline': {
border: '1px solid #5559CE !important',
transition: '0.5s all'
}
},
'& .muirtl-jv54yp-MuiList-root-MuiMultiSectionDigitalClockSection-root::after': {
display: 'none !important'
}
}}
/>
<p className={`absolute flex items-center right-[4px] h-[44px] py-[8px] px-[8px]
setValue(newValue);
}}
sx={{
"& .MuiFormLabel-root": {
top: "-4px !important",
},
"& .MuiInputBase-input": { padding: "12.5px 14px" },
"& .MuiOutlinedInput-notchedOutline": {
border: "1px solid #D7D7D7 !important",
},
"& .MuiInputBase-root": {
borderRadius: "8px !important",
},
".Mui-focused": {
"& .MuiOutlinedInput-notchedOutline": {
border: "1px solid #5559CE !important",
transition: "0.5s all",
},
},
"& .muirtl-jv54yp-MuiList-root-MuiMultiSectionDigitalClockSection-root::after":
{
display: "none !important",
},
}}
/>
<p
className={`absolute flex items-center right-[4px] h-[44px] py-[8px] px-[8px]
w-[calc(100%_-_52px)] text-[#7E7E7E] bg-[#FFFFFF] text-[14px] font-normal top-1/2 -translate-y-1/2
${disable && '!text-[rgba(126,126,126,0.5)]'}`}>{value}</p>
</LocalizationProvider>
</div>
)
${disable && "!text-[rgba(126,126,126,0.5)]"}`}
>
{value}
</p>
</LocalizationProvider>
</div>
);
}
export default TimePickerField
export default TimePickerField;
+26 -24
View File
@@ -1,28 +1,30 @@
import { TextField } from "@mui/material"
import { TextField } from "@mui/material";
function Field({ title, type, multiline, isPlaceHolder }) {
return (
<TextField
placeholder={isPlaceHolder && title}
label={!isPlaceHolder ? title : ''}
type={type || 'text'}
className="!w-full !mx-auto !bg-transparent"
sx={{
'& .MuiFormLabel-root': {
top: '-4px !important'
},
'& .MuiInputBase-input': { padding: '12.5px 14px' },
'& .MuiInputBase-root': { borderRadius: '6px !important' },
'& .MuiOutlinedInput-notchedOutline': { border: '1px solid #EFEFEF !important' },
".Mui-focused": {
'& .MuiOutlinedInput-notchedOutline': {
border: '1px solid #5559CE !important',
transition: '0.5s all'
}
}
}}
/>
)
return (
<TextField
placeholder={isPlaceHolder && title}
label={!isPlaceHolder ? title : ""}
type={type || "text"}
className="!w-full !mx-auto !bg-transparent"
sx={{
"& .MuiFormLabel-root": {
top: "-4px !important",
},
"& .MuiInputBase-input": { padding: "12.5px 14px" },
"& .MuiInputBase-root": { borderRadius: "6px !important" },
"& .MuiOutlinedInput-notchedOutline": {
border: "1px solid #EFEFEF !important",
},
".Mui-focused": {
"& .MuiOutlinedInput-notchedOutline": {
border: "1px solid #5559CE !important",
transition: "0.5s all",
},
},
}}
/>
);
}
export default Field;
export default Field;
+170 -146
View File
@@ -9,155 +9,179 @@ import DisLikeComment from "@/components/icons/DisLikeComment";
import ArrowUpComment from "@/components/icons/ArrowUpComment";
import LikeComment from "@/components/icons/LikeComment";
function ItemUser({ update, setUpdate, isReply, list, setList, data, loading }) {
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[nameLike] = lengthLike;
data[nameIsLike] = !data[nameIsLike];
setUpdate(!update);
function ItemUser({
update,
setUpdate,
isReply,
list,
setList,
data,
loading,
}) {
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[nameLike] = lengthLike;
data[nameIsLike] = !data[nameIsLike];
setUpdate(!update);
};
return (
<li className="w-full">
<div className="flex items-center justify-start gap-2">
{loading ? (
<Skeleton variant="circular" className="!min-w-[40px] !min-h-[40px]" />
) : (
<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}
width={40}
height={40}
alt="profile"
/>
)}
<div className="flex flex-col items-start justify-center gap-[8px]">
{loading ? (
<Skeleton variant="text" className="!min-w-[70px]" />
) : (
<>
<p className="text-[#343A40] text-[14px] md:text-[16px] font-medium">{data.name}</p>
<p className="text-[#7E7E7E] text-[12px] md:text-[14px] font-medium">3 روز پیش</p>
</>
)}
</div>
return (
<li className="w-full">
<div className="flex items-center justify-start gap-2">
{loading ? (
<Skeleton
variant="circular"
className="!min-w-[40px] !min-h-[40px]"
/>
) : (
<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}
width={40}
height={40}
alt="profile"
/>
)}
<div className="flex flex-col items-start justify-center gap-[8px]">
{loading ? (
<Skeleton variant="text" className="!min-w-[70px]" />
) : (
<>
<p className="text-[#343A40] text-[14px] md:text-[16px] font-medium">
{data.name}
</p>
<p className="text-[#7E7E7E] text-[12px] md:text-[14px] font-medium">
3 روز پیش
</p>
</>
)}
</div>
</div>
<div className="mt-2">
{loading ? (
<>
<Skeleton variant="text" className="!w-full !mt-8" />
<Skeleton variant="text" className="!w-1/3" />
</>
) : (
<p className="text-[#495057] text-[12px] md:text-[14px] font-normal leading-[20px] sm:leading-[24px] md:leading-[28px] lg:leading-[30px]">
{data.comment}
</p>
)}
<div className="flex items-center justify-start mt-2 gap-[28px]">
<div className="flex items-center justify-start gap-1">
<div
className="cursor-pointer"
onClick={() =>
handleLike(
data.is_like ? data.like - 1 : data.like + 1,
data,
"like",
"is_like"
)
}
>
{data.is_like ? <BoldLikeComment /> : <LikeComment />}
</div>
<div className="mt-2">
{loading ? (
<>
<Skeleton variant="text" className="!w-full !mt-8" />
<Skeleton variant="text" className="!w-1/3" />
</>
) : (
<p className="text-[#495057] text-[12px] md:text-[14px] font-normal leading-[20px] sm:leading-[24px] md:leading-[28px] lg:leading-[30px]">{data.comment}</p>
)}
<div className="flex items-center justify-start mt-2 gap-[28px]">
<div className="flex items-center justify-start gap-1">
<div
className="cursor-pointer"
onClick={() =>
handleLike(data.is_like ? data.like - 1 : data.like + 1, data, 'like', 'is_like')
}
>
{data.is_like ? (
<BoldLikeComment />
) : (
<LikeComment />
)}
</div>
{loading ? (
<Skeleton variant="text" className="!min-w-[8px]" />
) : (
<p className="text-[#6C757D] text-[12px] font-normal select-none">{data.like}</p>
)}
</div>
<div className="flex items-center justify-start gap-1">
<div
className="cursor-pointer"
onClick={() =>
handleLike(data.is_dislike ? data.dislike - 1 : data.dislike + 1, data, 'dislike', 'is_dislike')
}
>
{data.is_dislike ? (
<BoldDisLikeComment />
) : (
<DisLikeComment />
)}
</div>
{loading ? (
<Skeleton variant="text" className="!min-w-[8px]" />
) : (
<p className="text-[#6C757D] text-[12px] font-normal select-none">{data.dislike}</p>
)}
</div>
<Button
className="!text-[#495057] !text-[12px] !font-medium"
onClick={() => {
data.is_open_answer = !data.is_open_answer;
setUpdate(!update);
}}
variant="text"
>پاسخ</Button>
</div>
<div
className={`flex flex-col mt-2 justify-center overflow-hidden transition duration-500 items-start gap-2 mb-2
${data.is_open_answer ? 'max-h-fit' : 'max-h-0'}`}
>
<Field
type='text'
title='پاسخ شما...'
isPlaceHolder={true}
/>
<Button
variant="contained"
className="!p-2 !h-10 !text-[12px] !font-medium !text-[#FFF] sm:!py-[10px] md:!px-[12px] !rounded-[8px] !bg-[#5559CE]
{loading ? (
<Skeleton variant="text" className="!min-w-[8px]" />
) : (
<p className="text-[#6C757D] text-[12px] font-normal select-none">
{data.like}
</p>
)}
</div>
<div className="flex items-center justify-start gap-1">
<div
className="cursor-pointer"
onClick={() =>
handleLike(
data.is_dislike ? data.dislike - 1 : data.dislike + 1,
data,
"dislike",
"is_dislike"
)
}
>
{data.is_dislike ? <BoldDisLikeComment /> : <DisLikeComment />}
</div>
{loading ? (
<Skeleton variant="text" className="!min-w-[8px]" />
) : (
<p className="text-[#6C757D] text-[12px] font-normal select-none">
{data.dislike}
</p>
)}
</div>
<Button
className="!text-[#495057] !text-[12px] !font-medium"
onClick={() => {
data.is_open_answer = !data.is_open_answer;
setUpdate(!update);
}}
variant="text"
>
پاسخ
</Button>
</div>
<div
className={`flex flex-col mt-2 justify-center overflow-hidden transition duration-500 items-start gap-2 mb-2
${data.is_open_answer ? "max-h-fit" : "max-h-0"}`}
>
<Field type="text" title="پاسخ شما..." isPlaceHolder={true} />
<Button
variant="contained"
className="!p-2 !h-10 !text-[12px] !font-medium !text-[#FFF] sm:!py-[10px] md:!px-[12px] !rounded-[8px] !bg-[#5559CE]
!shadow-none sm:!shadow-[0px_4px_30px_0px_rgba(56,_160,_162,_0.30)]"
>
ارسال پاسخ
</Button>
</div>
{!!data.replays.length && (
<div className="flex items-center justify-start gap-1 my-2">
<Button
className="!text-[#0FA1B3] !text-[12px] !font-medium"
onClick={() => {
data.is_open_reply = !data.is_open_reply;
setUpdate(!update);
}}
>
مشاهده پاسخ ها ({data.replays.length})
<div className={`!mr-1 ${data.is_open_reply ? '!rotate-0' : '!rotate-180'}`}>
<ArrowUpComment />
</div>
</Button>
</div>
)}
<ul
className={`flex mr-12 flex-col justify-center transition-all duration-500 overflow-hidden items-start gap-12
${loading && 'w-full'}
${data.is_open_reply ? 'max-h-screen mt-12' : 'max-h-0'}`}
>
{data.replays.map((item, idx) => (
<ItemUser
key={idx}
data={item}
isReply={true}
update={update}
loading={loading}
setUpdate={setUpdate}
/>
))}
</ul>
</div>
</li>
)
>
ارسال پاسخ
</Button>
</div>
{!!data.replays.length && (
<div className="flex items-center justify-start gap-1 my-2">
<Button
className="!text-[#0FA1B3] !text-[12px] !font-medium"
onClick={() => {
data.is_open_reply = !data.is_open_reply;
setUpdate(!update);
}}
>
مشاهده پاسخ ها ({data.replays.length})
<div
className={`!mr-1 ${
data.is_open_reply ? "!rotate-0" : "!rotate-180"
}`}
>
<ArrowUpComment />
</div>
</Button>
</div>
)}
<ul
className={`flex mr-12 flex-col justify-center transition-all duration-500 overflow-hidden items-start gap-12
${loading && "w-full"}
${data.is_open_reply ? "max-h-screen mt-12" : "max-h-0"}`}
>
{data.replays.map((item, idx) => (
<ItemUser
key={idx}
data={item}
isReply={true}
update={update}
loading={loading}
setUpdate={setUpdate}
/>
))}
</ul>
</div>
</li>
);
}
export default ItemUser
export default ItemUser;
+27 -22
View File
@@ -1,27 +1,32 @@
'use client';
import { useState } from 'react';
import ItemUser from './ItemUser'
"use client";
import { useState } from "react";
import ItemUser from "./ItemUser";
function Comment({ data, loading }) {
const [list, setList] = useState(data.comments);
const [update, setUpdate] = useState(false);
const [list, setList] = useState(data.comments);
const [update, setUpdate] = useState(false);
return (
<ul className={`flex flex-col comment-list !pl-2.5 justify-start max-h-[492px] overflow-auto items-start gap-12 mt-2 ${false && 'w-full'}`}>
{data && !!data.comments.length && data.comments.map((item, idx) => (
<ItemUser
key={idx}
list={list}
data={item}
update={update}
setList={setList}
loading={loading}
setUpdate={setUpdate}
/>
))}
</ul>
)
return (
<ul
className={`flex flex-col comment-list !pl-2.5 justify-start max-h-[492px] overflow-auto items-start gap-12 mt-2 ${
false && "w-full"
}`}
>
{data &&
!!data.comments.length &&
data.comments.map((item, idx) => (
<ItemUser
key={idx}
list={list}
data={item}
update={update}
setList={setList}
loading={loading}
setUpdate={setUpdate}
/>
))}
</ul>
);
}
export default Comment;
export default Comment;
+12 -12
View File
@@ -1,16 +1,16 @@
import { Button as ButtonMUI } from '@mui/material'
import React from 'react'
import { Button as ButtonMUI } from "@mui/material";
import React from "react";
function ButtonDate({ handleClick, id, text }) {
return (
<ButtonMUI
onClick={handleClick}
aria-describedby={id}
className="!border-[#E9ECEF] !text-[#6C757D]"
>
{text}
</ButtonMUI>
)
return (
<ButtonMUI
onClick={handleClick}
aria-describedby={id}
className="!border-[#E9ECEF] !text-[#6C757D]"
>
{text}
</ButtonMUI>
);
}
export default ButtonDate
export default ButtonDate;
+34 -28
View File
@@ -1,32 +1,38 @@
import { TextField } from "@mui/material"
import { TextField } from "@mui/material";
function Field({ title, handleClick }) {
return (
<div className="relative">
<TextField
label={title}
className="!w-full !mx-auto !bg-[#FFF]"
sx={{
borderRadius: '8px !important',
'& .MuiFormLabel-root': { transform: 'translate(16px, 50%) scale(1) !important' },
'& .MuiInputLabel-shrink': { transform: 'translate(14px, -9px) scale(0.75) !important' },
'& .MuiInputBase-input': { padding: '12.5px 14px' },
'& .MuiInputBase-root': { borderRadius: '8px !important' },
'& .MuiOutlinedInput-notchedOutline': { border: '1px solid #E9ECEF !important' },
".Mui-focused": {
'& .MuiOutlinedInput-notchedOutline': {
border: '1px solid #0FA1B3 !important',
transition: '0.5s all'
}
}
}}
/>
<span
className="absolute cursor-pointer left-0 top-0 w-full h-full"
onClick={handleClick}
></span>
</div>
)
return (
<div className="relative">
<TextField
label={title}
className="!w-full !mx-auto !bg-[#FFF]"
sx={{
borderRadius: "8px !important",
"& .MuiFormLabel-root": {
transform: "translate(16px, 50%) scale(1) !important",
},
"& .MuiInputLabel-shrink": {
transform: "translate(14px, -9px) scale(0.75) !important",
},
"& .MuiInputBase-input": { padding: "12.5px 14px" },
"& .MuiInputBase-root": { borderRadius: "8px !important" },
"& .MuiOutlinedInput-notchedOutline": {
border: "1px solid #E9ECEF !important",
},
".Mui-focused": {
"& .MuiOutlinedInput-notchedOutline": {
border: "1px solid #0FA1B3 !important",
transition: "0.5s all",
},
},
}}
/>
<span
className="absolute cursor-pointer left-0 top-0 w-full h-full"
onClick={handleClick}
></span>
</div>
);
}
export default Field
export default Field;
+83 -84
View File
@@ -1,98 +1,97 @@
'use client';
"use client";
import { useEffect, useRef, useState } from 'react';
import { useEffect, useRef, useState } from "react";
import { DatePicker as DatePickerJalali } from "jalaali-react-date-picker";
import Image from 'next/image';
import { Button, Skeleton } from '@mui/material';
import Image from "next/image";
import { Button, Skeleton } from "@mui/material";
function DatePicker({ date, updateDate }) {
const nextIconDatePicker = useRef();
const nextIconDatePicker = useRef();
const [startDate, setStartDate] = useState(null);
const [endDate, setEndDate] = useState();
const [loading, setLoading] = useState(true);
const [startDate, setStartDate] = useState(null);
const [endDate, setEndDate] = useState();
const [loading, setLoading] = useState(true);
const handleStartDateChange = (date) => {
if (date) {
setStartDate(date);
setEndDate(null); // Clear end date if start date is selected
// updateDate(date); // Notify parent about the selected date
}
};
const handleEndDateChange = (date) => {
if (date) {
setEndDate(date);
setStartDate(null); // Clear start date if end date is selected
// updateDate(date); // Notify parent about the selected date
}
};
const handleDisableDate = e => {
const today = new Date();
return today >= e._d
const handleStartDateChange = (date) => {
if (date) {
setStartDate(date);
setEndDate(null); // Clear end date if start date is selected
// updateDate(date); // Notify parent about the selected date
}
};
useEffect(() => {
if (nextIconDatePicker.current) {
nextIconDatePicker.current.click()
setLoading(false)
}
}, [nextIconDatePicker])
const handleEndDateChange = (date) => {
if (date) {
setEndDate(date);
setStartDate(null); // Clear start date if end date is selected
// updateDate(date); // Notify parent about the selected date
}
};
return (
<div className='flex items-start justify-evenly w-full'>
<div className='w-1/2 relative flex justify-center'>
<DatePickerJalali
value={startDate}
className={`w-full ${loading ? 'opacity-0' : 'opacity-100'}`}
timePicker={false}
onChange={handleStartDateChange}
disabledDates={e => handleDisableDate(e)}
const handleDisableDate = (e) => {
const today = new Date();
return today >= e._d;
};
useEffect(() => {
if (nextIconDatePicker.current) {
nextIconDatePicker.current.click();
setLoading(false);
}
}, [nextIconDatePicker]);
return (
<div className="flex items-start justify-evenly w-full">
<div className="w-1/2 relative flex justify-center">
<DatePickerJalali
value={startDate}
className={`w-full ${loading ? "opacity-0" : "opacity-100"}`}
timePicker={false}
onChange={handleStartDateChange}
disabledDates={(e) => handleDisableDate(e)}
/>
{loading && (
<Skeleton
variant="rectangular"
className="!w-[300px] !rounded-[6px] !absolute !top-0 !right-1/2 !translate-x-1/2 !z-10"
height={352}
/>
)}
</div>
<div className="w-1/2 hidden md:flex lg:hidden xl:flex">
<div className="w-full relative flex justify-center">
<DatePickerJalali
value={endDate}
timePicker={false}
className={`w-full ${loading ? "opacity-0" : "opacity-100"}`}
nextIcon={
<Button
className="!min-w-0 !p-0 !rounded-full"
ref={nextIconDatePicker}
onClick={(e) => e.preventDefault()}
>
<Image
src="/assets/icons/arrow-right.svg"
className="icon-left-datepicker"
height={24}
width={24}
/>
{loading && (
<Skeleton
variant="rectangular"
className='!w-[300px] !rounded-[6px] !absolute !top-0 !right-1/2 !translate-x-1/2 !z-10'
height={352}
/>
)}
</div>
<div className='w-1/2 hidden md:flex lg:hidden xl:flex'>
<div className='w-full relative flex justify-center'>
<DatePickerJalali
value={endDate}
timePicker={false}
className={`w-full ${loading ? 'opacity-0' : 'opacity-100'}`}
nextIcon={
<Button
className='!min-w-0 !p-0 !rounded-full'
ref={nextIconDatePicker}
onClick={e => e.preventDefault()}
>
<Image
src='/assets/icons/arrow-right.svg'
className='icon-left-datepicker'
height={24}
width={24}
/>
</Button>
}
onChange={handleEndDateChange}
disabledDates={e => handleDisableDate(e)}
/>
{loading && (
<Skeleton
variant="rectangular"
className='!w-[300px] !rounded-[6px] !absolute !top-0 !right-1/2 !translate-x-1/2 !z-10'
height={352}
/>
)}
</div>
</div>
</Button>
}
onChange={handleEndDateChange}
disabledDates={(e) => handleDisableDate(e)}
/>
{loading && (
<Skeleton
variant="rectangular"
className="!w-[300px] !rounded-[6px] !absolute !top-0 !right-1/2 !translate-x-1/2 !z-10"
height={352}
/>
)}
</div>
);
</div>
</div>
);
}
export default DatePicker;
+24 -24
View File
@@ -1,32 +1,32 @@
import { Button } from "@mui/material";
function Hours({ doctor, hour, setHour, value, nameHours }) {
return (
<ul
className="grid grid-cols-3 md:grid-cols-4 lg:grid-cols-6 gap-x-[16px] gap-y-[12px] sm:gap-y-[16px] md:gap-y-[20px] lg:gap-y-[24px] mt-[24px] mb-[40px]"
>
{doctor[nameHours[value]].map((item, idx) => (
<li
key={idx}
>
<Button
onClick={() => setHour(idx)}
disabled={!item.active}
className={`
return (
<ul className="grid grid-cols-3 md:grid-cols-4 lg:grid-cols-6 gap-x-[16px] gap-y-[12px] sm:gap-y-[16px] md:gap-y-[20px] lg:gap-y-[24px] mt-[24px] mb-[40px]">
{doctor[nameHours[value]].map((item, idx) => (
<li key={idx}>
<Button
onClick={() => setHour(idx)}
disabled={!item.active}
className={`
!w-full !rounded-[8px] !bg-[#EFEFEF] !grid !place-items-center !py-[10px] !px-[14px] !h-[40px] md:!h-[42px] lg:!h-[44px]
${idx === hour ? '!bg-[#F79463] ' : ''}
${idx === hour ? "!bg-[#F79463] " : ""}
`}
>
<p className={`
>
<p
className={`
text-[16px] font-semibold text-[#525252]
${item.active ? 'text-[#525252]' : 'text-[#D7D7D7]'}
${idx === hour ? '!text-[#FAFAFA] ' : ''}
`}>{item.hour}</p>
</Button>
</li>
))}
</ul>
)
${item.active ? "text-[#525252]" : "text-[#D7D7D7]"}
${idx === hour ? "!text-[#FAFAFA] " : ""}
`}
>
{item.hour}
</p>
</Button>
</li>
))}
</ul>
);
}
export default Hours;
export default Hours;
+19 -20
View File
@@ -1,4 +1,4 @@
'use client';
"use client";
import { useState } from "react";
import Hours from "./Hours";
@@ -6,11 +6,10 @@ import Tabs from "../../Tabs";
import { Button } from "@mui/material";
import ArrowLeftB from "@/components/icons/ArrowLeftB";
const listTab = ['صبح', 'بعد از ظهر'];
const nameHours = ['hours_morning', 'hours_afternoon']
const listTab = ["صبح", "بعد از ظهر"];
const nameHours = ["hours_morning", "hours_afternoon"];
function DateTime({ doctor, setStep, setIsError, locateVisit }) {
const [value, setValue] = useState(0);
const [hour, setHour] = useState(0);
@@ -21,21 +20,21 @@ function DateTime({ doctor, setStep, setIsError, locateVisit }) {
<Tabs
isSm={true}
style={{
'.MuiTabs-indicator': {
height: '4px',
borderRadius: '8px',
background: '#F17732'
".MuiTabs-indicator": {
height: "4px",
borderRadius: "8px",
background: "#F17732",
},
'& .MuiTabs-flexContainer': {
borderBottom: '2px solid #EFEFEF',
marginBottom: '1px'
"& .MuiTabs-flexContainer": {
borderBottom: "2px solid #EFEFEF",
marginBottom: "1px",
},
'& .mui-11pdt05-MuiButtonBase-root-MuiTab-root.Mui-selected': {
color: '#F17732 !important'
"& .mui-11pdt05-MuiButtonBase-root-MuiTab-root.Mui-selected": {
color: "#F17732 !important",
},
"& .MuiButtonBase-root.Mui-selected": {
color: "#F17732 !important",
},
'& .MuiButtonBase-root.Mui-selected': {
color: '#F17732 !important'
}
}}
value={value}
listTab={listTab}
@@ -53,8 +52,8 @@ function DateTime({ doctor, setStep, setIsError, locateVisit }) {
className="!gap-[4px] !shadow-none !px-[12px] !py-[8px] md:!py-[9px] !w-full md:!w-fit !min-w-[157px]"
onClick={() => {
if (locateVisit) {
localStorage.setItem('doctor-id', doctor?.id);
setStep(prev => prev + 1);
localStorage.setItem("doctor-id", doctor?.id);
setStep((prev) => prev + 1);
} else {
setIsError(true);
}
@@ -66,7 +65,7 @@ function DateTime({ doctor, setStep, setIsError, locateVisit }) {
</Button>
</div>
</div>
)
);
}
export default DateTime
export default DateTime;
+55 -57
View File
@@ -3,63 +3,61 @@ import { Autocomplete, TextField } from "@mui/material";
import { styleTextSelectRight } from "@/mui";
function AutoCompleteSelect({ list, isError, updateData, name, label }) {
return (
<Autocomplete
disablePortal
options={list}
className="!w-full !rounded-lg"
onChange={(event) =>
updateData &&
updateData(event, name)
}
sx={{
...styleTextSelectRight,
// Hide Icon Number
'& input::-webkit-outer-spin-button, & input::-webkit-inner-spin-button': {
display: 'none'
},
'& input[type=number]': {
MozAppearance: 'textfield'
},
'& .MuiInputBase-root': {
borderRadius: 2,
padding: '5px 16px !important'
},
'& .MuiOutlinedInput-notchedOutline': {
border: '1px solid #D7D7D7'
},
'& .MuiInput-underline:hover:not(.Mui-disabled):before, .MuiOutlinedInput-notchedOutline': {
borderColor: "#D7D7D7 !important"
},
'& .muirtl-1kiro5a-MuiInputBase-root-MuiOutlinedInput-root.Mui-focused .MuiOutlinedInput-notchedOutline': {
border: '1px solid #5559CE !important'
},
'& .MuiOutlinedInput-notchedOutline': {
border: isError ? '1px solid red !important' : ''
}
}}
renderInput={params =>
<TextField
fullWidth
{...params}
InputProps={{
...params.InputProps,
endAdornment: (
<div
className="absolute left-4"
>
<BottomSelect />
</div>
)
}}
placeholder={label}
sx={{
borderRadius: '8px'
}}
/>
}
return (
<Autocomplete
disablePortal
options={list}
className="!w-full !rounded-lg"
onChange={(event) => updateData && updateData(event, name)}
sx={{
...styleTextSelectRight,
// Hide Icon Number
"& input::-webkit-outer-spin-button, & input::-webkit-inner-spin-button":
{
display: "none",
},
"& input[type=number]": {
MozAppearance: "textfield",
},
"& .MuiInputBase-root": {
borderRadius: 2,
padding: "5px 16px !important",
},
"& .MuiOutlinedInput-notchedOutline": {
border: "1px solid #D7D7D7",
},
"& .MuiInput-underline:hover:not(.Mui-disabled):before, .MuiOutlinedInput-notchedOutline":
{
borderColor: "#D7D7D7 !important",
},
"& .muirtl-1kiro5a-MuiInputBase-root-MuiOutlinedInput-root.Mui-focused .MuiOutlinedInput-notchedOutline":
{
border: "1px solid #5559CE !important",
},
"& .MuiOutlinedInput-notchedOutline": {
border: isError ? "1px solid red !important" : "",
},
}}
renderInput={(params) => (
<TextField
fullWidth
{...params}
InputProps={{
...params.InputProps,
endAdornment: (
<div className="absolute left-4">
<BottomSelect />
</div>
),
}}
placeholder={label}
sx={{
borderRadius: "8px",
}}
/>
)
)}
/>
);
}
export default AutoCompleteSelect
export default AutoCompleteSelect;
+33 -30
View File
@@ -1,35 +1,38 @@
import { TextField } from "@mui/material"
import { styleTextSelectRight } from "@/mui"
import { TextField } from "@mui/material";
import { styleTextSelectRight } from "@/mui";
function Field({ title, type, isPlaceHolder }) {
return (
<TextField
label={title}
dir="rtl"
type={type || 'text'}
className="!w-full !mx-auto !bg-[#FFF]"
sx={{
...styleTextSelectRight,
// Hide Icon Number
'& input::-webkit-outer-spin-button, & input::-webkit-inner-spin-button': {
display: 'none'
},
'& input[type=number]': {
MozAppearance: 'textfield'
},
return (
<TextField
label={title}
dir="rtl"
type={type || "text"}
className="!w-full !mx-auto !bg-[#FFF]"
sx={{
...styleTextSelectRight,
// Hide Icon Number
"& input::-webkit-outer-spin-button, & input::-webkit-inner-spin-button":
{
display: "none",
},
"& input[type=number]": {
MozAppearance: "textfield",
},
'& .MuiInputBase-input': { padding: '12.5px 14px' },
'& .MuiInputBase-root': { borderRadius: '6px !important' },
'& .MuiOutlinedInput-notchedOutline': { border: '1px solid #E9ECEF !important' },
".Mui-focused": {
'& .MuiOutlinedInput-notchedOutline': {
border: '1px solid #0FA1B3 !important',
transition: '0.5s all'
}
}
}}
/>
)
"& .MuiInputBase-input": { padding: "12.5px 14px" },
"& .MuiInputBase-root": { borderRadius: "6px !important" },
"& .MuiOutlinedInput-notchedOutline": {
border: "1px solid #E9ECEF !important",
},
".Mui-focused": {
"& .MuiOutlinedInput-notchedOutline": {
border: "1px solid #0FA1B3 !important",
transition: "0.5s all",
},
},
}}
/>
);
}
export default Field
export default Field;
+17 -11
View File
@@ -1,17 +1,23 @@
function HeadPageList({ children, title, detail }) {
return (
<div className="bg-head-menu !bg-no-repeat !bg-cover !bg-center">
<div className="
return (
<div className="bg-head-menu !bg-no-repeat !bg-cover !bg-center">
<div
className="
padding-responsive flex flex-col items-center gap-[25px]
pt-[calc(12px_+_75px_+_32px)] sm:pt-[calc(21px_+_75px_+_45px)] md:pt-[calc(30px_+_75px_+_58px)] lg:pt-[calc(40px_+_75px_+_78px)]
pb-[62px] sm:pb-[69px] md:pb-[76px] lg:pb-[85px]
">
<p className="text-[#3B3B3B] text-[16px] sm:text-[19px] md:text-[22px] lg:text-[24px] text-center font-bold">{title}</p>
<p className="text-[#3B3B3B] text-[14px] md:text-[16px] text-center font-normal">{detail}</p>
{children}
</div>
</div>
)
"
>
<p className="text-[#3B3B3B] text-[16px] sm:text-[19px] md:text-[22px] lg:text-[24px] text-center font-bold">
{title}
</p>
<p className="text-[#3B3B3B] text-[14px] md:text-[16px] text-center font-normal">
{detail}
</p>
{children}
</div>
</div>
);
}
export default HeadPageList
export default HeadPageList;
+7 -9
View File
@@ -1,13 +1,11 @@
import { Skeleton } from '@mui/material'
import { Skeleton } from "@mui/material";
function CircularLoading({ loading, width, height, children }) {
return loading ? (
<Skeleton
variant="circular"
height={height}
width={width}
/>
) : children
return loading ? (
<Skeleton variant="circular" height={height} width={width} />
) : (
children
);
}
export default CircularLoading
export default CircularLoading;
+12 -10
View File
@@ -1,14 +1,16 @@
import { Skeleton } from "@mui/material"
import { Skeleton } from "@mui/material";
function CustomLoading({ width, height, children, loading }) {
return loading ? (
<Skeleton
className={width === 'full' ? '!w-full' : ''}
height={height}
variant="rounded"
width={width}
/>
) : children
return loading ? (
<Skeleton
className={width === "full" ? "!w-full" : ""}
height={height}
variant="rounded"
width={width}
/>
) : (
children
);
}
export default CustomLoading
export default CustomLoading;
+11 -7
View File
@@ -1,14 +1,18 @@
import { Skeleton } from "@mui/material"
import { Skeleton } from "@mui/material";
function MultilineLoading({ loading, width, height, children, line }) {
return loading ? Array(line).fill({}).map(_ => (
<Skeleton
className={`${width === 'full' ? '!w-full' : ''} !my-2`}
return loading
? Array(line)
.fill({})
.map((_) => (
<Skeleton
className={`${width === "full" ? "!w-full" : ""} !my-2`}
variant="rounded"
height={height}
width={width}
/>
)) : children
/>
))
: children;
}
export default MultilineLoading
export default MultilineLoading;
+12 -10
View File
@@ -1,14 +1,16 @@
import { Skeleton } from '@mui/material'
import { Skeleton } from "@mui/material";
function TextLoading({ loading, width, height, children }) {
return loading ? (
<Skeleton
className={width === 'full' ? '!w-full' : ''}
variant="rounded"
height={height}
width={width}
/>
) : children
return loading ? (
<Skeleton
className={width === "full" ? "!w-full" : ""}
variant="rounded"
height={height}
width={width}
/>
) : (
children
);
}
export default TextLoading
export default TextLoading;
+38 -34
View File
@@ -1,40 +1,44 @@
import CloseModalD from '@/components/icons/CloseModalD'
import Image from 'next/image'
import CloseModalD from "@/components/icons/CloseModalD";
import Image from "next/image";
const maps = [
{ src: '/assets/images/snapp.png', name: 'snapp' },
{ src: '/assets/images/tapsi.png', name: 'tapsi' },
{ src: '/assets/images/maps.png', name: 'maps' },
{ src: '/assets/images/balad.png', name: 'balad' },
{ src: '/assets/images/waze.png', name: 'waze' }
]
{ src: "/assets/images/snapp.png", name: "snapp" },
{ src: "/assets/images/tapsi.png", name: "tapsi" },
{ src: "/assets/images/maps.png", name: "maps" },
{ src: "/assets/images/balad.png", name: "balad" },
{ src: "/assets/images/waze.png", name: "waze" },
];
function Content({ handleClose }) {
return (
<>
<div className="flex items-center justify-between">
<p className="text-[#3B3B3B] text-[14px] sm:text-[16px] md:text-[18px] lg:text-[20px] font-medium">باز شدن با</p>
<div className="cursor-pointer" onClick={handleClose}>
<CloseModalD />
</div>
</div>
<span className="bg-[#EFEFEF] block h-px w-full mt-[12px] mb-[22px]"></span>
<ul className="flex items-center justify-center gap-[32px] md:gap-[36px] lg:gap-[40px] mx-auto flex-wrap md:flex-nowrap md:mx-[72px]">
{maps.map((item, idx) => (
<li className="flex items-center flex-col justify-center gap-1">
<Image
className='w-[32px] h-[32px] lg:w-[40px] lg:h-[40px]'
src={item.src}
alt="icon app"
height={40}
width={40}
/>
<p className="text-[#3B3B3B] font-normal text-[14px]">{item.name}</p>
</li>
))}
</ul>
</>
)
return (
<>
<div className="flex items-center justify-between">
<p className="text-[#3B3B3B] text-[14px] sm:text-[16px] md:text-[18px] lg:text-[20px] font-medium">
باز شدن با
</p>
<div className="cursor-pointer" onClick={handleClose}>
<CloseModalD />
</div>
</div>
<span className="bg-[#EFEFEF] block h-px w-full mt-[12px] mb-[22px]"></span>
<ul className="flex items-center justify-center gap-[32px] md:gap-[36px] lg:gap-[40px] mx-auto flex-wrap md:flex-nowrap md:mx-[72px]">
{maps.map((item, idx) => (
<li className="flex items-center flex-col justify-center gap-1">
<Image
className="w-[32px] h-[32px] lg:w-[40px] lg:h-[40px]"
src={item.src}
alt="icon app"
height={40}
width={40}
/>
<p className="text-[#3B3B3B] font-normal text-[14px]">
{item.name}
</p>
</li>
))}
</ul>
</>
);
}
export default Content
export default Content;
+36 -43
View File
@@ -1,52 +1,45 @@
'use client';
"use client";
import { Drawer, Modal } from "@mui/material";
import { styleDefault } from "@/mui";
import Content from "./Content";
function ModalOpenLocation({ open, setOpen, handleClose, children }) {
const toggleDrawer = (newOpen) => () => {
setOpen(newOpen);
};
const toggleDrawer = (newOpen) => () => {
setOpen(newOpen);
};
return (
<>
{/* Button Modal */}
{children}
{/* Content Modal */}
<Modal
open={open}
onClose={handleClose}
className="!hidden md:!flex"
>
<div
style={styleDefault}
className="!pt-[12px] !pb-[28px] !px-[24px] !bg-[#FAFAFA] !rounded-[8px] !overflow-hidden"
>
<Content onClose={handleClose} />
</div>
</Modal>
<Drawer
open={open}
anchor="bottom"
onClose={toggleDrawer(false)}
className="!flex md:!hidden"
sx={{
'& .MuiPaper-root': {
borderRadius: '25px 25px 0px 0px !important',
overflow: 'hidden'
}
}}
>
<div
className="!pt-[12px] !pb-[28px] !px-[24px] !bg-[#FAFAFA] !rounded-[8px] !overflow-hidden !shadow-[0px_1px_24.8px_0px_rgba(155,_155,_155,_0.27)]"
>
<Content handleClose={handleClose} />
</div>
</Drawer>
</>
)
return (
<>
{/* Button Modal */}
{children}
{/* Content Modal */}
<Modal open={open} onClose={handleClose} className="!hidden md:!flex">
<div
style={styleDefault}
className="!pt-[12px] !pb-[28px] !px-[24px] !bg-[#FAFAFA] !rounded-[8px] !overflow-hidden"
>
<Content onClose={handleClose} />
</div>
</Modal>
<Drawer
open={open}
anchor="bottom"
onClose={toggleDrawer(false)}
className="!flex md:!hidden"
sx={{
"& .MuiPaper-root": {
borderRadius: "25px 25px 0px 0px !important",
overflow: "hidden",
},
}}
>
<div className="!pt-[12px] !pb-[28px] !px-[24px] !bg-[#FAFAFA] !rounded-[8px] !overflow-hidden !shadow-[0px_1px_24.8px_0px_rgba(155,_155,_155,_0.27)]">
<Content handleClose={handleClose} />
</div>
</Drawer>
</>
);
}
export default ModalOpenLocation
export default ModalOpenLocation;