change design all page & component page booking and account & cleancode

This commit is contained in:
Ehsan
2024-09-01 20:43:53 +03:30
parent 2afd79b84d
commit bb154ac63f
46 changed files with 685 additions and 523 deletions
+2 -3
View File
@@ -3,7 +3,7 @@
import AutoCompleteSelect from "@/app/component/element/AutoCompleteSelect"
import { useState } from "react";
function PlaceVisit() {
function PlaceVisit({ locateVisit, setLocateVisit, isError }) {
const clinics = [
{ label: 'درمانگاه رازی', id: 10 },
@@ -11,14 +11,13 @@ function PlaceVisit() {
{ label: 'درمانگاه مرکزی', id: 30 }
];
const [locateVisit, setLocateVisit] = useState();
const updateData = event => setLocateVisit(event.target.innerText);
return (
<div className="flex flex-col items-start gap-[19px] justify-start">
<p className="text-[#3B3B3B] text-[14px] md:text-[16px] font-bold">1. انتخاب محل ویزیت</p>
<AutoCompleteSelect
isError={isError && !locateVisit}
updateData={updateData}
label='درمانگاه'
list={clinics}
+4 -1
View File
@@ -1,11 +1,14 @@
import DateTime from "@/app/component/date/dateTime"
function Hour({ doctor }) {
function Hour({ doctor, setStep, setIsError, locateVisit }) {
return (
<div className="flex mt-[24px] flex-col items-start gap-[12px] justify-start">
<p className="text-[#3B3B3B] text-[14px] md:text-[16px] font-bold">3. انتخاب ساعت</p>
<DateTime
doctor={doctor}
setStep={setStep}
setIsError={setIsError}
locateVisit={locateVisit}
/>
</div>
)
+18 -3
View File
@@ -1,14 +1,29 @@
import { useState } from "react";
import Hour from "./hour"
import PlaceVisit from "./PlaceVisit"
import Time from "./Time"
function Date({ doctor }) {
function Date({ doctor, setStep }) {
const [locateVisit, setLocateVisit] = useState();
const [isError, setIsError] = useState(false);
return (
<div className="w-full lg:w-[61%]">
<div className="p-0 lg:p-[24px] rounded-[8px] border border-solid border-transparent lg:border-[#EFEFEF] bg-transparent lg:bg-[#FFF]">
<PlaceVisit />
<PlaceVisit
setLocateVisit={setLocateVisit}
locateVisit={locateVisit}
isError={isError}
/>
<Time />
<Hour doctor={doctor} />
<Hour
setLocateVisit={setLocateVisit}
locateVisit={locateVisit}
setIsError={setIsError}
setStep={setStep}
doctor={doctor}
/>
</div>
</div>
)
+17
View File
@@ -0,0 +1,17 @@
function Content({ isConfirmed, children, title }) {
return (
<div className='flex w-full flex-col items-start justify-start gap-[8px] sm:gap-[10px] md:gap-[13px] lg:gap-[16px]'>
<div className='flex min-h-[32px] items-center justify-start gap-[8px] md:gap-[6px] lg:gap-[4px]'>
<p className="text-[#525252] text-[14px] font-medium">{title}</p>
{isConfirmed && (
<p
className='py-[4px] md:py-[2px] leading-[8px] sm:leading-[14px] md:leading-[21px] lg:leading-[28px] px-[5px] bg-[#05BA58] rounded-[40px] text-[#FFF] text-[10px] md:text-[12px] font-normal'
>تایید شده</p>
)}
</div>
{children}
</div>
)
}
export default Content
+42
View File
@@ -0,0 +1,42 @@
import EditOrangeA from "@/components/icons/EditOrangeA"
import { Button, TextField } from "@mui/material"
function EditField({ changeData, data, name }) {
return (
<div className="relative w-full">
<TextField
value={data?.value}
disabled={!data?.isEdit}
type='text'
className="!bg-[#FFF] !w-full res-field-account"
onChange={e => {
changeData(e.target.value, 'value', name)
}}
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'
}
}
}}
/>
<Button
className="!absolute !left-[8px] !top-1/2 !-translate-y-1/2 !min-w-fit !p-1"
onClick={() => {
changeData(!data.isEdit, 'isEdit', name)
}}
>
<EditOrangeA />
</Button>
</div>
)
}
export default EditField
+36
View File
@@ -0,0 +1,36 @@
import AutoCompleteSelect from "@/app/component/element/AutoCompleteSelect";
import EditField from "./EditField";
import Content from "./Content";
const bime = [
{ label: 'بیمه 1', id: 10 },
{ label: 'بیمه 2', id: 20 },
{ label: 'بیمه 3', id: 30 }
];
function Form({ changeData, data, updateSelect, isForAnother }) {
return (
<div className="grid mt-[12px] sm:mt-[14px] md:mt-[17px] lg:mt-[20px] items-start
justify-center gap-x-[24px] gap-y-[12px] md:gap-y-[14px] lg:gap-y-[16px] grid-cols-1 sm:grid-cols-2">
<Content title='شماره موبایل' isConfirmed={isForAnother ? false : true}>
<EditField changeData={changeData} data={data?.phone} name='phone' />
</Content>
<Content title='کد ملی'>
<EditField changeData={changeData} data={data?.codemeli} name='codemeli' />
</Content>
<Content title='نام و نام خانوادگی'>
<EditField changeData={changeData} data={data?.name} name='name' />
</Content>
<Content title='نوع بیمه'>
<AutoCompleteSelect
updateData={updateSelect}
label='نوع بیمه'
name='first'
list={bime}
/>
</Content>
</div>
)
}
export default Form
+67 -9
View File
@@ -1,16 +1,74 @@
import Address from "./Address";
import Head from "./Head";
import { useState } from "react";
import { Button } from "@mui/material";
import AddCircleBlueA from "@/components/icons/AddCircleBlueA";
import ArrowLeftB from "@/components/icons/ArrowLeftB";
import ButtonFixed from "../paying/ButtonFixed";
import Form from "./Form";
function Detail({ isForAnother, setStep, setIsForAnother, data, setData, fadeElement, setIsPay }) {
const [selected, setSelected] = useState({
first: '',
second: ''
});
const changeData = (value, type, name) =>
setData({
...data,
[name]: {
...data[name],
[type]: value
}
});
const updateSelect = (event, name) => setSelected({ ...selected, [name]: event.target.innerText })
function Detail({ doctor }) {
return (
<div className="h-fit lg:h-screen w-full lg:w-[39%]">
// ${typePay === 'success' || typePay === 'failed' ? 'bg-transparent border-transparent md:bg-[#FFF] md:border-[#EFEFEF]' : ''}
<div className="w-full lg:w-[59%]">
<div
className="p-0 lg:p-[16px] sticky rounded-[8px] bg-transparent lg:bg-[#FFF] border border-solid border-transparent lg:border-[#EFEFEF]
top-[calc(12px_+_75px_+_32px)] sm:top-[calc(21px_+_75px_+_45px)] md:top-[calc(30px_+_75px_+_58px)] lg:top-[calc(40px_+_75px_+_78px)]"
className={`opacity-page bg-[#FFF] border border-solid border-[#EFEFEF]
rounded-[8px] p-[12px] sm:p-[16px] md:p-[20px] lg:p-[24px]
`}
>
<Head doctor={doctor} />
<span className="block w-full bg-[#EFEFEF] h-px my-[16px]"></span>
<Address doctor={doctor} />
<p className="text-[#3B3B3B] text-[20px] font-bold">
{isForAnother ? 'اطلاعات کاربر جدید' : 'اطلاعات حساب کاربری'}
</p>
<Form
isForAnother={isForAnother}
updateSelect={updateSelect}
changeData={changeData}
data={data}
/>
{!isForAnother && (
<Button
className="!flex !items-center !justify-start !gap-[8px] !mt-[12px] sm:!mt-[16px] md:!mt-[20px] lg:!mt-[24px] !p-1"
onClick={() => {
setIsForAnother(true)
setData({
phone: { value: '09121056987', isEdit: false },
codemeli: { value: '1741025645', isEdit: false },
name: { value: 'ساغر صابری نژاد', isEdit: false }
});
}}
>
<AddCircleBlueA />
<p className="text-[#5559CE] text-[16px] font-medium">دریافت نوبت برای فرد دیگر </p>
</Button>
)}
<ButtonFixed>
<Button
className={`
!flex !w-full md:!w-fit
!gap-[4px] md:!mr-auto !px-[12px] !py-[8px] md:!py-[9px] !min-w-[150px]
${isForAnother ? '!mt-0 md:!mt-[40px]' : '!mt-0 md:!mt-[32px]'}`}
variant="contained"
onClick={() => setStep(prev => prev + 1)}
>
<p className="text-[#EFEFEF] text-[16px] font-medium">ثبت اطلاعات</p>
<ArrowLeftB />
</Button>
</ButtonFixed>
</div>
</div>
)
+44
View File
@@ -0,0 +1,44 @@
import Link from "next/link";
import { Button } from "@mui/material";
import RedoA from "@/components/icons/RedoA";
import RefreshA from "@/components/icons/RefreshA";
import InfoCircleRedA from "@/components/icons/InfoCircleRedA";
function FailedPay({ setStep, fadeElement }) {
return (
<div className='w-full lg:w-[59%]'>
<div
className={`opacity-page bg-transparent lg:bg-[#FFF] border border-solid border-transparent lg:border-[#EFEFEF]
rounded-[8px] p-[12px] sm:p-[16px] md:p-[20px] lg:p-[24px]`}
>
<div className="mt-[7px]">
<div className="flex flex-col justify-center items-center gap-[14px]">
<InfoCircleRedA />
<p className="text-[#D32F2F] text-[16px] md:text-[18px] lg:text-[20px] font-bold">پرداخت شما انجام نشد.</p>
</div>
<div className="flex mt-[32px] sm:mt-[29px] md:mt-[27px] lg:mt-[24px] items-center justify-center gap-[24px]">
<Link href='/'>
<Button
variant="outlined"
className="!flex !rounded-[8px] !items-center !p-2 !justify-center !gap-[4px]"
>
<RedoA />
<p className="text-[#5559CE] text-[16px] font-medium">صفحه اصلی</p>
</Button>
</Link>
<Button
variant="contained"
onClick={() => setStep(prev => prev - 2)}
className="!flex !rounded-[8px] !items-center !p-2 !justify-center !gap-[4px]"
>
<RefreshA />
<p className="text-[#FAFAFA] text-[16px] font-medium">تلاش دوباره</p>
</Button>
</div>
</div>
</div>
</div>
)
}
export default FailedPay
+10 -6
View File
@@ -1,13 +1,17 @@
import Date from "./date";
import Detail from "./detail";
import Information from "./information"
import Location from "./location"
function BookingPage({ doctor }) {
function BookingPage({ doctor, children, isFirst, disableSide }) {
return (
<div
className="flex flex-col lg:flex-row justify-center gap-0 lg:gap-[24px] padding-responsive
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)]">
<Detail doctor={doctor} />
<Date doctor={doctor} />
{isFirst ? (
<Location disableSide={disableSide} doctor={doctor} />
) : (
<Information disableSide={disableSide} doctor={doctor} />
)}
{children}
</div>
)
}
+88
View File
@@ -0,0 +1,88 @@
import ArrowLeftOrangeA from "@/components/icons/ArrowLeftOrangeA"
import CalendarA from "@/components/icons/CalendarA"
import ClockA from "@/components/icons/ClockA"
import LocationA from "@/components/icons/LocationA"
import TickCircleOrange from "@/components/icons/TickCircleOrange"
import { Button } from "@mui/material"
function Detail({ doctor }) {
return (
<div className="">
<ul className="flex flex-col items-start justify-start gap-[24px]">
<li className="flex items-center justify-start gap-[4px]">
<div className="w-[18px] h-[18px] md:w-[20px] md:h-[20px]">
<LocationA />
</div>
<p className="text-[#616161] text-[14px] md:text-[16px] font-normal">آدرس: {doctor.location}</p>
</li>
<li className="flex items-center justify-between w-full">
<div className="flex items-center justify-start gap-[4px]">
<div className="w-[18px] h-[18px] md:w-[20px] md:h-[20px]">
<CalendarA />
</div>
<div className="flex items-center justify-start">
<p className="text-[#616161] text-[14px] md:text-[16px] font-medium">تاریخ نوبت: </p>
<p className="text-[#2F2F2F] text-[14px] md:text-[16px] font-medium mr-1">13 خرداد 1403</p>
</div>
</div>
<Button
className="!p-1 !flex !items-center !justify-end !gap-[2px]"
variant="text"
>
<p className="!text-[#F17732] !text-[12px] md:!text-[14px] !font-normal">تغییر </p>
<div className="w-[16px] h-[16px] sm:w-[18px] sm:h-[18px] md:w-[21px] md:h-[21px] lg:w-[24px] lg:h-[24px]">
<ArrowLeftOrangeA />
</div>
</Button>
</li>
<li className="flex items-center justify-between w-full">
<div className="flex items-center justify-start gap-[4px]">
<div className="w-[18px] h-[18px] md:w-[20px] md:h-[20px]">
<ClockA />
</div>
<div className="flex items-center justify-start">
<p className="text-[#616161] text-[14px] md:text-[16px] font-medium">زمان نوبت: </p>
<p className="text-[#2F2F2F] text-[14px] md:text-[16px] font-medium mr-1">ساعت 17:20</p>
</div>
</div>
<Button
className="!p-1 !flex !items-center !justify-end !gap-[2px]"
variant="text"
>
<p className="!text-[#F17732] !text-[12px] md:!text-[14px] !font-normal">تغییر </p>
<div className="w-[16px] h-[16px] sm:w-[18px] sm:h-[18px] md:w-[21px] md:h-[21px] lg:w-[24px] lg:h-[24px]">
<ArrowLeftOrangeA />
</div>
</Button>
</li>
</ul>
<span
className="mt-[10px] sm:mt-[16px] md:mt-[22px] lg:mt-[28px]
mb-[8px] sm:mb-[13px] md:mb-[19px] lg:mb-[24px]
w-full h-px bg-[#D7D7D7] block"
></span>
<ul className="flex flex-col items-start justify-start gap-[8px] sm:gap-[13px] md:gap-[19px] lg:gap-[24px]">
<li className="flex items-center justify-start gap-[4px] md:gap-[6px] lg:gap-[8px]">
<div
className="min-w-[16px] sm:min-w-[19px] md:min-w-[21px] lg:min-w-[24px] min-h-[16px] sm:min-h-[19px] md:min-h-[21px] lg:min-h-[24px]
w-[16px] sm:w-[19px] md:w-[21px] lg:w-[24px] h-[16px] sm:h-[19px] md:h-[21px] lg:h-[24px]"
>
<TickCircleOrange />
</div>
<p className="text-[#616161] text-[16px] font-normal">فقط در صورت لغو نوبت تا 5 ساعت قبل از زمان ویزیت، امکان استرداد وجه ممکن می باشد.</p>
</li>
<li className="flex items-center justify-start gap-[4px] md:gap-[6px] lg:gap-[8px]">
<div
className="min-w-[16px] sm:min-w-[19px] md:min-w-[21px] lg:min-w-[24px] min-h-[16px] sm:min-h-[19px] md:min-h-[21px] lg:min-h-[24px]
w-[16px] sm:w-[19px] md:w-[21px] lg:w-[24px] h-[16px] sm:h-[19px] md:h-[21px] lg:h-[24px]"
>
<TickCircleOrange />
</div>
<p className="text-[#616161] text-[16px] font-normal">لطفا به موقع در مطب حضور داشته باشید.</p>
</li>
</ul>
</div>
)
}
export default Detail
+29
View File
@@ -0,0 +1,29 @@
import Image from "next/image"
function Head({ doctor }) {
return (
<div className="
flex items-center justify-start
gap-[8px] sm:gap-[11px] md:gap-[14px] lg:gap-[16px]
mt-[8px] sm:mt-[13px] md:mt-[19px] lg:mt-[24px]
mb-[12px] sm:mb-[19px] md:mb-[25px] lg:lg:mb-[32px]
">
<Image
className="
w-[40px] sm:w-[58px] md:w-[77px] lg:w-[95px]
h-[40px] sm:h-[58px] md:h-[77px] lg:h-[95px]
"
alt="profile doctor"
src={doctor.img}
height={95}
width={95}
/>
<div className="flex flex-col items-start justify-center gap-[8px] sm:gap-[12px] md:gap-[16px] lg:gap-[20px]">
<p className="text-[#3B3B3B] text-[14px] sm:text-[16px] md:text-[18px] lg:text-[20px] font-medium">{doctor.name}</p>
<p className="text-[#616161] text-[14px] md:text-[16px] font-medium">تخصص: {doctor.expertise}</p>
</div>
</div>
)
}
export default Head
+22
View File
@@ -0,0 +1,22 @@
import Detail from "./Detail"
import Head from "./Head"
function Information({ doctor, typePay, isPay, disableSide }) {
return (
<div className={`w-full lg:w-[41%] relative ${disableSide ? 'hidden lg:flex' : ''}`}>
<div
className={`p-[24px] sticky right-0 w-full opacity-page rounded-[8px] border
border-solid border-[#EFEFEF] bg-[#FFF]
top-[calc(12px_+_75px_+_32px)] sm:top-[calc(21px_+_75px_+_45px)] md:top-[calc(30px_+_75px_+_58px)] lg:top-[calc(40px_+_75px_+_78px)]
${typePay === 'success' || typePay === 'failed' ? 'hidden md:block' : 'block'}
`}
>
<p className="text-[#3B3B3B] text-[20px] font-bold">جزئیات نوبت</p>
<Head doctor={doctor} />
<Detail doctor={doctor} />
</div>
</div>
)
}
export default Information
@@ -1,5 +1,3 @@
import React from 'react'
function Address({ doctor }) {
return (
<ul className='hidden mt-[4px] lg:flex flex-col'>
@@ -1,5 +1,4 @@
import Image from 'next/image'
import React from 'react'
function Head({ doctor }) {
return (
+19
View File
@@ -0,0 +1,19 @@
import Address from "./Address";
import Head from "./Head";
function Location({ doctor }) {
return (
<div className="h-fit lg:h-screen w-full lg:w-[39%]">
<div
className="p-0 lg:p-[16px] sticky rounded-[8px] bg-transparent lg:bg-[#FFF] border border-solid border-transparent lg:border-[#EFEFEF]
top-[calc(12px_+_75px_+_32px)] sm:top-[calc(21px_+_75px_+_45px)] md:top-[calc(30px_+_75px_+_58px)] lg:top-[calc(40px_+_75px_+_78px)]"
>
<Head doctor={doctor} />
<span className="block bg-[#EFEFEF] lg:bg-transparent w-full h-px lg:my-[6px] mt-[16px]"></span>
<Address doctor={doctor} />
</div>
</div>
)
}
export default Location
+15
View File
@@ -0,0 +1,15 @@
import React from 'react'
function ButtonFixed({ children }) {
return (
<div
className="!fixed md:!relative !bottom-0 !right-0 bg-[#FFF] border-0 border-t
md:border-t-transparent border-[#D7D7D7] z-10
!w-full sm:!w-full !p-[16px] sm:!px-[52px] md:!ml-0 md:!p-0 md:!w-full"
>
{children}
</div>
)
}
export default ButtonFixed
+38
View File
@@ -0,0 +1,38 @@
import ArrowLeftB from '@/components/icons/ArrowLeftB';
import { Button } from '@mui/material';
import ButtonFixed from './ButtonFixed';
function Paying({ setTypePay, fadeElement, setStep }) {
return (
<div className='w-full lg:w-[59%]'>
<div
className={`opacity-page bg-[#FFF] border border-solid border-[#EFEFEF]
rounded-[8px] p-[12px] sm:p-[16px] md:p-[20px] lg:p-[24px]`}
>
<p className="text-[#3B3B3B] text-[14px] sm:text-[16px] md:text-[18px] lg:text-[20px] font-bold">
اطلاعات پرداخت
</p>
<div className='flex justify-between items-center mt-[12px] sm:mt-[18px] md:mt-[24px] lg:mt-[30px]'>
<p className='text-[#616161] text-[14px] md:text-[16px] font-medium'>مبلغ پیش پرداخت (بیعانه) : </p>
<p className='text-[#525252] text-[14px] md:text-[16px] font-bold'>20،000 تومان</p>
</div>
<span className='bg-[#D7D7D7] hidden md:block h-px w-full mt-[32px] mb-[25px]'></span>
<ButtonFixed>
<div className='flex items-center justify-between gap-2'>
<p className='text-[#616161] md:text-[#3B3B3B] text-[14px] md:text-[16px] font-bold'>مبلغ قابل پرداخت : 20،000 تومان</p>
<Button
className='!gap-[4px] !mr-auto !flex !px-[12px] !p-[7px] md:!py-[9px] !min-w-[157px]'
onClick={() => setStep(prev => prev + 1)}
variant="contained"
>
<p className="text-[#EFEFEF] text-[16px] font-medium">پرداخت نهایی</p>
<ArrowLeftB />
</Button>
</div>
</ButtonFixed>
</div>
</div>
)
}
export default Paying
+46
View File
@@ -0,0 +1,46 @@
import ArrowLeftBlueA from "@/components/icons/ArrowLeftBlueA"
import TickCircleGreenA from "@/components/icons/TickCircleGreenA"
import { Button } from "@mui/material"
import Link from "next/link"
function SuccessPay({ setStep }) {
return (
<div className='w-full lg:w-[59%]'>
<div
className={`opacity-page bg-transparent lg:bg-[#FFF] border border-solid border-transparent lg:border-[#EFEFEF]
rounded-[8px] p-[12px] sm:p-[16px] md:p-[20px] lg:p-[24px]`}
>
<div className="pt-[8px] pb-[4px] grid place-items-center">
<div className="flex flex-col justify-center items-center gap-[14px]">
<TickCircleGreenA />
<p className="text-[#3B3B3B] text-[20px] font-bold">پرداخت شما با موفقیت انجام شد.</p>
</div>
<p
className="text-[#3B3B3B] text-[16px] font-normal
mt-[24px] sm:mt-[26px] md:mt-[29px] lg:mt-[32px]
mb-[24px] md:mb-[16px]"
>برای نمایش نوبت ها به قسمت نوبت های من بروید. </p>
<div className="flex w-full md:hidden flex-col justify-center items-center mb-[32px]">
<span className="w-full block h-px bg-[#EFEFEF]"></span>
<div className="flex items-center justify-between my-[20px] gap-[80px]">
<p className="text-[#616161] text-[14px] font-medium">مقدار پرداخت شده: </p>
<p className="text-[#05BA58] text-[14px] font-bold">20،000 تومان</p>
</div>
<span className="w-full block h-px bg-[#EFEFEF]"></span>
</div>
<Link href='/dashboard'>
<Button
variant="text"
className="!flex !items-center !justify-center !gap-[4px]"
>
<p className="text-[16px] font-medium text-[#5559CE]">برو به نوبت های من</p>
<ArrowLeftBlueA />
</Button>
</Link>
</div>
</div>
</div>
)
}
export default SuccessPay