From c45a161fcba0e17897e10f07a5f0461323879ce5 Mon Sep 17 00:00:00 2001 From: Ehsan Date: Thu, 5 Sep 2024 22:20:18 +0330 Subject: [PATCH] add loading all page & change bugs --- app/component/ItemDoctor.js | 86 +++++++++-------- app/component/comment/index.js | 6 +- app/component/loading/Circular.js | 13 +++ app/component/loading/Custom.js | 14 +++ app/component/loading/Multiline.js | 14 +++ app/component/loading/Text.js | 14 +++ app/globals.css | 4 + components/blog/detail/Caption.js | 60 +++++++----- components/blog/detail/SocialMedia.js | 17 ++-- components/blog/detail/commentUser/index.js | 4 +- components/blog/detail/index.js | 8 +- components/blog/head/index.js | 28 ++++-- components/blog/index.js | 18 +++- components/blog/relatedContent/Item.js | 45 +++++---- components/blog/relatedContent/index.js | 3 +- components/blogs/Head.js | 92 ++++++++++++------- components/blogs/index.js | 17 +++- components/blogs/latestArticles/Article.js | 40 +++++--- components/blogs/latestArticles/index.js | 3 +- .../clinic/components/about/ContentDetail.js | 7 +- .../clinic/components/about/ListBime.js | 29 +++--- .../clinic/components/about/Services.js | 11 ++- .../clinic/components/about/Specialties.js | 11 ++- .../clinic/components/about/iamges/Images.js | 25 ----- .../clinic/components/about/iamges/List.js | 38 -------- .../clinic/components/about/iamges/Slider.js | 21 ----- .../clinic/components/about/images/Images.js | 30 ++++++ .../clinic/components/about/images/List.js | 55 +++++++++++ .../clinic/components/about/images/Slider.js | 24 +++++ components/clinic/components/about/index.js | 33 ++++--- .../components/contact/ContentDetail.js | 12 ++- .../clinic/components/contact/Detail.js | 6 +- components/clinic/components/contact/index.js | 39 ++++---- components/clinic/components/doctors/List.js | 3 +- components/clinic/components/doctors/index.js | 4 +- components/clinic/index.js | 16 +++- components/clinics/index.js | 15 ++- components/clinics/list/ItemClinic.js | 39 +++++--- components/clinics/list/index.js | 5 +- components/dashboard/index.js | 1 - .../dashboard/userAccount/ContentTabs.js | 20 ++-- .../userAccount/tabs/comments/Comment.js | 64 ++++++++----- .../userAccount/tabs/comments/index.js | 3 +- .../userAccount/tabs/messages/Message.js | 16 +++- .../userAccount/tabs/messages/index.js | 3 +- .../userAccount/tabs/transactions/Card.js | 72 ++++++++++----- .../userAccount/tabs/transactions/List.js | 72 ++++++++++----- .../userAccount/tabs/transactions/index.js | 4 +- .../dashboard/userAccount/tabs/turns/Card.js | 64 ++++++++----- .../dashboard/userAccount/tabs/turns/List.js | 73 ++++++++++----- .../dashboard/userAccount/tabs/turns/index.js | 4 +- .../tabs/turns/isTurnsDetails/ButtonData.js | 5 +- .../tabs/turns/isTurnsDetails/DetailLg.js | 90 +++++++++++------- .../tabs/turns/isTurnsDetails/DetailSm.js | 84 +++++++++++------ .../tabs/turns/isTurnsDetails/Head.js | 9 +- .../tabs/turns/isTurnsDetails/index.js | 7 +- .../tabs/turns/isTurnsDetails/modal/index.js | 8 +- .../doctor/appointmentList/ItemAppointment.js | 33 ++++--- components/doctor/appointmentList/index.js | 3 +- components/doctor/detailDoctor/Title.js | 57 +++++++----- .../doctor/detailDoctor/cards/AboutDcotor.js | 36 +++++--- .../cards/comments/chart/ProgressAll.js | 47 +++++----- .../cards/comments/chart/index.js | 65 +++++++------ .../detailDoctor/cards/comments/index.js | 7 +- .../detailDoctor/cards/locations/index.js | 23 +++-- components/doctor/detailDoctor/index.js | 10 +- components/doctor/index.js | 27 ++++-- components/doctors/index.js | 12 ++- components/doctors/listDoctors/index.js | 7 +- components/specialties/index.js | 20 +++- .../specialties/list/ItemSpecialties.js | 11 ++- components/specialties/list/index.js | 3 +- 72 files changed, 1208 insertions(+), 661 deletions(-) create mode 100644 app/component/loading/Circular.js create mode 100644 app/component/loading/Custom.js create mode 100644 app/component/loading/Multiline.js create mode 100644 app/component/loading/Text.js delete mode 100644 components/clinic/components/about/iamges/Images.js delete mode 100644 components/clinic/components/about/iamges/List.js delete mode 100644 components/clinic/components/about/iamges/Slider.js create mode 100644 components/clinic/components/about/images/Images.js create mode 100644 components/clinic/components/about/images/List.js create mode 100644 components/clinic/components/about/images/Slider.js diff --git a/app/component/ItemDoctor.js b/app/component/ItemDoctor.js index a961231..4788639 100644 --- a/app/component/ItemDoctor.js +++ b/app/component/ItemDoctor.js @@ -1,5 +1,5 @@ import Image from "next/image"; -import { Button } from "@mui/material"; +import { Button, Skeleton } from "@mui/material"; // Icons import ArrowLeftD from "@/components/icons/ArrowLeftD"; @@ -7,60 +7,74 @@ import ClockD from "@/components/icons/ClockD"; import LikeD from "@/components/icons/LikeD"; import PointD from "@/components/icons/PointD"; import Link from "next/link"; +import CustomLoading from "./loading/Custom"; +import TextLoading from "./loading/Text"; +import CircularLoading from "./loading/Circular"; -function ItemDoctor({ doctor }) { +function ItemDoctor({ doctor, loading }) { return (
  • {/* Detail Doctor */}
    - image-doctor + + image-doctor +
    -

    {doctor.name}

    -

    تخصص: {doctor.expertise}

    -
    -
    - -

    {doctor.satisfaction}%

    + +

    {doctor.name}

    +
    + +

    تخصص: {doctor.expertise}

    +
    + +
    +
    + +

    {doctor.satisfaction}%

    +
    +
    + +

    {doctor.point}

    +
    -
    - -

    {doctor.point}

    -
    -
    +
    {/* Hours of work */} -
    +
    -

    ساعت کاری: {doctor.hours_of_work}

    + +

    ساعت کاری: {doctor.hours_of_work}

    +
    -

    +

    {doctor.free_turn ? - `اولین نوبت آزاد: ${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}` : + 'نوبت ندارد' + }

    + {/* Arrow */} diff --git a/app/component/comment/index.js b/app/component/comment/index.js index e39e956..6354d2f 100644 --- a/app/component/comment/index.js +++ b/app/component/comment/index.js @@ -2,21 +2,21 @@ import { useState } from 'react'; import ItemUser from './ItemUser' -function Comment({ data }) { +function Comment({ data, loading }) { const [list, setList] = useState(data.comments); const [update, setUpdate] = useState(false); return ( -
      +
        {data && !!data.comments.length && data.comments.map((item, idx) => ( ))} diff --git a/app/component/loading/Circular.js b/app/component/loading/Circular.js new file mode 100644 index 0000000..6bb8053 --- /dev/null +++ b/app/component/loading/Circular.js @@ -0,0 +1,13 @@ +import { Skeleton } from '@mui/material' + +function CircularLoading({ loading, width, height, children }) { + return loading ? ( + + ) : children +} + +export default CircularLoading \ No newline at end of file diff --git a/app/component/loading/Custom.js b/app/component/loading/Custom.js new file mode 100644 index 0000000..5038791 --- /dev/null +++ b/app/component/loading/Custom.js @@ -0,0 +1,14 @@ +import { Skeleton } from "@mui/material" + +function CustomLoading({ width, height, children, loading }) { + return loading ? ( + + ) : children +} + +export default CustomLoading \ No newline at end of file diff --git a/app/component/loading/Multiline.js b/app/component/loading/Multiline.js new file mode 100644 index 0000000..097310e --- /dev/null +++ b/app/component/loading/Multiline.js @@ -0,0 +1,14 @@ +import { Skeleton } from "@mui/material" + +function MultilineLoading({ loading, width, height, children, line }) { + return loading ? Array(line).fill({}).map(_ => ( + + )) : children +} + +export default MultilineLoading \ No newline at end of file diff --git a/app/component/loading/Text.js b/app/component/loading/Text.js new file mode 100644 index 0000000..2668568 --- /dev/null +++ b/app/component/loading/Text.js @@ -0,0 +1,14 @@ +import { Skeleton } from '@mui/material' + +function TextLoading({ loading, width, height, children }) { + return loading ? ( + + ) : children +} + +export default TextLoading \ No newline at end of file diff --git a/app/globals.css b/app/globals.css index bd760fc..20f88dd 100644 --- a/app/globals.css +++ b/app/globals.css @@ -286,6 +286,10 @@ html { height: 0; } +.comment-list::-webkit-scrollbar { + height: 10px; +} + .opacity-page { animation: loadPageOpacity; animation-duration: 1s; diff --git a/components/blog/detail/Caption.js b/components/blog/detail/Caption.js index 75adb16..005cd67 100644 --- a/components/blog/detail/Caption.js +++ b/components/blog/detail/Caption.js @@ -1,31 +1,45 @@ +import CustomLoading from '@/app/component/loading/Custom' +import MultilineLoading from '@/app/component/loading/Multiline' import Image from 'next/image' import React from 'react' -function Caption({ data }) { +function Caption({ data, loading }) { return ( <> - cover-blog -
        - cover-blog -
        + + cover-blog + +
        + +
        + +
        + + cover-blog + +
        + +
        + +
        ) } diff --git a/components/blog/detail/SocialMedia.js b/components/blog/detail/SocialMedia.js index 78e468a..2f8478c 100644 --- a/components/blog/detail/SocialMedia.js +++ b/components/blog/detail/SocialMedia.js @@ -1,3 +1,4 @@ +import CircularLoading from "@/app/component/loading/Circular" import LinkedinB from "@/components/icons/LinkedinB" import TelegramB from "@/components/icons/TelegramB" import WhatsappB from "@/components/icons/WhatsappB" @@ -8,16 +9,18 @@ const socials = [ ] -function SocialMedia() { +function SocialMedia({ loading }) { return (
          {socials.map((item, idx) => ( -
        • - {item} -
        • + +
        • + {item} +
        • +
          ))}
        diff --git a/components/blog/detail/commentUser/index.js b/components/blog/detail/commentUser/index.js index 97bad41..7c82b6f 100644 --- a/components/blog/detail/commentUser/index.js +++ b/components/blog/detail/commentUser/index.js @@ -4,14 +4,14 @@ import Underline from '@/components/icons/Underline' import React from 'react' import AddComment from './AddComment' -function CommentUser({ data }) { +function CommentUser({ data, loading }) { return (
        - +
        ) } diff --git a/components/blog/detail/index.js b/components/blog/detail/index.js index a636fa4..2cd4952 100644 --- a/components/blog/detail/index.js +++ b/components/blog/detail/index.js @@ -2,12 +2,12 @@ import Caption from "./Caption"; import SocialMedia from "./SocialMedia"; import CommentUser from "./commentUser"; -function Detail({ data }) { +function Detail({ data, loading }) { return (
        - - - + + +
        ) } diff --git a/components/blog/head/index.js b/components/blog/head/index.js index 4f9892c..4277cea 100644 --- a/components/blog/head/index.js +++ b/components/blog/head/index.js @@ -1,20 +1,32 @@ -function Head({ data }) { +import TextLoading from "@/app/component/loading/Text" + +function Head({ data, loading }) { return (
        -
        -

        بلاگ {'>'}

        -

        پوست و مو {'>'}

        -

        روش های خانگی محافظت از پوست در تابستان

        + +
        +

        بلاگ {'>'}

        +

        پوست و مو {'>'}

        +

        روش های خانگی محافظت از پوست در تابستان

        +
        +
        +
        + +

        روش های خانگی محافظت از پوست در تابستان

        +
        -

        روش های خانگی محافظت از پوست در تابستان

        تاریخ انتشار:

        -

        {data.date_of_release}

        + +

        {data.date_of_release}

        +

        زمان مطالعه:

        -

        {data.time}

        + +

        {data.time}

        +
        diff --git a/components/blog/index.js b/components/blog/index.js index 58dfd84..5b45f52 100644 --- a/components/blog/index.js +++ b/components/blog/index.js @@ -1,14 +1,26 @@ +'use client' + +import { useEffect, useState } from "react"; import Detail from "./detail"; import Head from "./head"; import RelatedContent from "./relatedContent"; function BlogPage({ article, articles }) { + + const [loading, setLoading] = useState(true); + + useEffect(() => { + setTimeout(() => { + setLoading(false); + }, 2000); + }, []); + return (
        - +
        - - + +
        ) diff --git a/components/blog/relatedContent/Item.js b/components/blog/relatedContent/Item.js index b4b0d49..9f1e3d1 100644 --- a/components/blog/relatedContent/Item.js +++ b/components/blog/relatedContent/Item.js @@ -1,31 +1,40 @@ +import CircularLoading from "@/app/component/loading/Circular"; +import CustomLoading from "@/app/component/loading/Custom"; +import TextLoading from "@/app/component/loading/Text"; import Image from "next/image"; import Link from "next/link"; -function Item({ data, idx }) { +function Item({ data, idx, loading }) { return (
      • - - article - -
        - -

        {data.title}

        + src={data.src} + alt="article" + height={88} + width={97} + /> -

        تاریخ انتشار: {data.date_of_release}

        + +
        + + +

        {data.title}

        + +
        + +

        تاریخ انتشار: {data.date_of_release}

        +
        {data.id > idx + 1 && ( diff --git a/components/blog/relatedContent/index.js b/components/blog/relatedContent/index.js index a55b19a..2b741fb 100644 --- a/components/blog/relatedContent/index.js +++ b/components/blog/relatedContent/index.js @@ -3,7 +3,7 @@ import UnderlineLG from '@/components/icons/UnderlineLG' import React from 'react' import Item from './Item' -function RelatedContent({ data }) { +function RelatedContent({ data, loading }) { return (
        @@ -15,6 +15,7 @@ function RelatedContent({ data }) { idx={idx} data={item} key={item.id} + loading={loading} /> ))}
      diff --git a/components/blogs/Head.js b/components/blogs/Head.js index 76e1a3e..ca7b3da 100644 --- a/components/blogs/Head.js +++ b/components/blogs/Head.js @@ -1,47 +1,73 @@ +import CustomLoading from '@/app/component/loading/Custom' +import TextLoading from '@/app/component/loading/Text' import Image from 'next/image' import Link from 'next/link' -function Head() { +function Head({ loading }) { return (
      - head blog -

      روش های خانگی محافظت از پوست در تابستان

      - -
      -
      - - head blog -

      فواید نوشیدن آب برای سلامتی

      - - - head blog -

      راهکارهای ساده برای درمان سر درد

      - -
      - + head blog -

      تغذیه مناسب برای کاهش فشار خون

      +
      +
      + +

      روش های خانگی محافظت از پوست در تابستان

      +
      +
      + +
      +
      + + + head blog + +
      + +

      فواید نوشیدن آب برای سلامتی

      +
      +
      + + + + head blog + +
      + +

      راهکارهای ساده برای درمان سر درد

      +
      +
      + +
      + + + head blog + +
      + +

      تغذیه مناسب برای کاهش فشار خون

      +
      +
      diff --git a/components/blogs/index.js b/components/blogs/index.js index 0cfe84b..3beca2a 100644 --- a/components/blogs/index.js +++ b/components/blogs/index.js @@ -1,13 +1,26 @@ +'use client'; + +import { useEffect, useState } from "react"; + import Head from "./Head"; import Title from "./title"; import LatestArticles from "./latestArticles"; function BlogsPage() { + + const [loading, setLoading] = useState(true); + + useEffect(() => { + setTimeout(() => { + setLoading(false); + }, 2000); + }, []); + return (
      - <Head /> - <LatestArticles /> + <Head loading={loading} /> + <LatestArticles loading={loading} /> </div> ) } diff --git a/components/blogs/latestArticles/Article.js b/components/blogs/latestArticles/Article.js index f4ab002..8165d1f 100644 --- a/components/blogs/latestArticles/Article.js +++ b/components/blogs/latestArticles/Article.js @@ -1,25 +1,37 @@ +import CustomLoading from '@/app/component/loading/Custom'; +import TextLoading from '@/app/component/loading/Text'; import Image from 'next/image' import Link from 'next/link'; -function Article({ data }) { +function Article({ data, loading }) { return ( <li className='rounded-[8px] overflow-hidden bg-[#FFF] shadow-[0px_0px_41px_0px_rgba(173,_181,_189,_0.15)]'> - <Link href={`/blog/${data.id}`}> - <Image - className='w-full' - alt="article-img" - src={data.src} - height={217} - width={392} - /> - </Link> - <div className='p-[12px] md:p-[14px] lg:p-[16px]'> + <CustomLoading width='full' height={200} loading={loading}> <Link href={`/blog/${data.id}`}> - <p className='text-[#3B3B3B] mb-[12px] md:mb-[14px] lg:mb-[16px] text-[16px] font-bold'>{data.title}</p> + <Image + className='w-full' + alt="article-img" + src={data.src} + height={217} + width={392} + /> </Link> + </CustomLoading> + <div className='p-[12px] md:p-[14px] lg:p-[16px]'> + <div className={loading ? 'mb-[12px] md:mb-[14px] lg:mb-[16px]' : ''}> + <TextLoading width={150} height={18} loading={loading}> + <Link href={`/blog/${data.id}`}> + <p className='text-[#3B3B3B] mb-[12px] md:mb-[14px] lg:mb-[16px] text-[16px] font-bold'>{data.title}</p> + </Link> + </TextLoading> + </div> <div className='flex items-center justify-start gap-[35px]'> - <p className='text-[#9B9B9B] text-[14px] font-medium'>تاریخ انتشار: {data.date_of_release}</p> - <p className='text-[#9B9B9B] text-[14px] font-medium'>زمان مطالعه: {data.time}</p> + <TextLoading width={100} height={18} loading={loading}> + <p className='text-[#9B9B9B] text-[14px] font-medium'>تاریخ انتشار: {data.date_of_release}</p> + </TextLoading> + <TextLoading width={110} height={18} loading={loading}> + <p className='text-[#9B9B9B] text-[14px] font-medium'>زمان مطالعه: {data.time}</p> + </TextLoading> </div> </div> </li> diff --git a/components/blogs/latestArticles/index.js b/components/blogs/latestArticles/index.js index 0dedb18..a86bba5 100644 --- a/components/blogs/latestArticles/index.js +++ b/components/blogs/latestArticles/index.js @@ -2,7 +2,7 @@ import articles from '@/data/articles.json'; import Article from "./Article"; import Pagination from '@/app/component/Pagination'; -function LatestArticles() { +function LatestArticles({ loading }) { return ( <div> <p className="text-[#3B3B3B] text-[20px] font-bold my-[16px] md:my-[20px] lg:my-[24px]">جدیدترین مقاله ها</p> @@ -11,6 +11,7 @@ function LatestArticles() { <Article data={item} key={item.id} + loading={loading} /> ))} </ul> diff --git a/components/clinic/components/about/ContentDetail.js b/components/clinic/components/about/ContentDetail.js index a101b88..fd0d36e 100644 --- a/components/clinic/components/about/ContentDetail.js +++ b/components/clinic/components/about/ContentDetail.js @@ -1,9 +1,12 @@ +import TextLoading from '@/app/component/loading/Text' import React from 'react' -function ContentDetail({ head, children }) { +function ContentDetail({ head, children, loading }) { return ( <div className='my-[24px]'> - <p className='text-[#3B3B3B] text-[20px] font-bold'>{head}</p> + <TextLoading width={200} height={20} loading={loading}> + <p className='text-[#3B3B3B] text-[20px] font-bold'>{head}</p> + </TextLoading> <div className='mt-[16px]'> {children} </div> diff --git a/components/clinic/components/about/ListBime.js b/components/clinic/components/about/ListBime.js index 16a61b1..59f07f2 100644 --- a/components/clinic/components/about/ListBime.js +++ b/components/clinic/components/about/ListBime.js @@ -1,21 +1,24 @@ +import CustomLoading from '@/app/component/loading/Custom' import Image from 'next/image' -function ListBime({ data }) { +function ListBime({ data, loading }) { return ( <ul className='flex overflow-auto hidden-scroll mt-[8px] items-center justify-start xl:justify-center gap-[8px] sm:gap-[13px] md:gap-[19px] lg:gap-[24px]'> {data.list_bime.map((item, idx) => ( - <li - key={idx} - className='p-[16px] min-w-[156px] w-full border border-[#EFEFEF] flex flex-col items-center justify-center gap-[20px]' - > - <Image - src={item.img} - height={92} - width={92} - alt='bime' - /> - <p className='text-[#525252] text-[16px] font-medium'>{item.name}</p> - </li> + <CustomLoading width={156} height={110} loading={loading}> + <li + key={idx} + className='p-[16px] min-w-[156px] w-full border border-[#EFEFEF] flex flex-col items-center justify-center gap-[20px]' + > + <Image + src={item.img} + height={92} + width={92} + alt='bime' + /> + <p className='text-[#525252] text-[16px] font-medium'>{item.name}</p> + </li> + </CustomLoading> ))} </ul> ) diff --git a/components/clinic/components/about/Services.js b/components/clinic/components/about/Services.js index 0baabfa..6a5d3b0 100644 --- a/components/clinic/components/about/Services.js +++ b/components/clinic/components/about/Services.js @@ -1,6 +1,7 @@ +import TextLoading from '@/app/component/loading/Text'; import TickCircleOrange from '@/components/icons/TickCircleOrange'; -function Services({ data }) { +function Services({ data, loading }) { return ( <ul className=' mt-[8px] w-full p-[22px] rounded-[8px] bg-[#FFF] flex flex-wrap items-center justify-start lg:grid grid-cols-4 @@ -14,12 +15,14 @@ function Services({ data }) { <div className='min-w-[24px] min-h-[24px]'> <TickCircleOrange /> </div> - <p - className={` + <TextLoading width={80} height={18} loading={loading}> + <p + className={` text-[16px] font-normal ${idx === 0 ? 'text-[#F17732]' : 'text-[#525252]'} `} - >{item}</p> + >{item}</p> + </TextLoading> </li> ))} </ul> diff --git a/components/clinic/components/about/Specialties.js b/components/clinic/components/about/Specialties.js index c16b7ad..5963f06 100644 --- a/components/clinic/components/about/Specialties.js +++ b/components/clinic/components/about/Specialties.js @@ -1,6 +1,7 @@ +import TextLoading from '@/app/component/loading/Text'; import TickCircleOrange from '@/components/icons/TickCircleOrange'; -function Specialties({ data }) { +function Specialties({ data, loading }) { return ( <ul className=' mt-[8px] w-full p-[22px] rounded-[8px] bg-[#FFF] flex flex-wrap items-center justify-start lg:grid grid-cols-4 @@ -14,12 +15,14 @@ function Specialties({ data }) { <div className='min-w-[24px] min-h-[24px]'> <TickCircleOrange /> </div> - <p - className={` + <TextLoading width={80} height={18} loading={loading}> + <p + className={` text-[16px] font-normal ${idx === 0 ? 'text-[#F17732]' : 'text-[#525252]'} `} - >{item}</p> + >{item}</p> + </TextLoading> </li> ))} </ul> diff --git a/components/clinic/components/about/iamges/Images.js b/components/clinic/components/about/iamges/Images.js deleted file mode 100644 index 4154a73..0000000 --- a/components/clinic/components/about/iamges/Images.js +++ /dev/null @@ -1,25 +0,0 @@ -import List from './List'; -import Slider from './Slider'; -import Image from 'next/image'; - -function Images({ data }) { - return ( - <div - className=' - flex flex-col md:flex-row items-center mb-[8px] justify-center w-full - gap-[12px] md:gap-[18px] lg:gap-[24px] - '> - <Image - className="rounded-[8px] overflow-hidden" - src={data.images_clinic[0]} - alt="img clinic" - height={432} - width={600} - /> - <List data={data} /> - <Slider data={data} /> - </div> - ) -} - -export default Images \ No newline at end of file diff --git a/components/clinic/components/about/iamges/List.js b/components/clinic/components/about/iamges/List.js deleted file mode 100644 index 6d8e059..0000000 --- a/components/clinic/components/about/iamges/List.js +++ /dev/null @@ -1,38 +0,0 @@ -import Image from 'next/image'; - -function List({ data }) { - return ( - <div className="hidden md:grid grid-cols-2 gap-[16px] lg:gap-[24px]"> - <Image - className="rounded-[8px] overflow-hidden" - src={data.images_clinic[1]} - alt="img clinic" - height={204} - width={288} - /> - <Image - className="rounded-[8px] overflow-hidden" - src={data.images_clinic[2]} - alt="img clinic" - height={204} - width={288} - /> - <Image - className="rounded-[8px] overflow-hidden" - src={data.images_clinic[3]} - alt="img clinic" - height={204} - width={288} - /> - <Image - className="rounded-[8px] overflow-hidden" - src={data.images_clinic[4]} - alt="img clinic" - height={204} - width={288} - /> - </div> - ) -} - -export default List \ No newline at end of file diff --git a/components/clinic/components/about/iamges/Slider.js b/components/clinic/components/about/iamges/Slider.js deleted file mode 100644 index a629cc7..0000000 --- a/components/clinic/components/about/iamges/Slider.js +++ /dev/null @@ -1,21 +0,0 @@ -import Image from "next/image" - -function Slider({ data }) { - return ( - <ul className="flex md:hidden gap-2 w-full justify-start items-center overflow-auto hidden-scroll"> - {[...data.images_clinic, ...data.images_clinic].map((item, idx) => - idx !== 0 ? ( - <Image - key={idx} - src={item} - width={90} - height={90} - alt="image clinic" - className="min-w-[90px] min-h-[90px] object-cover rounded-[8px] overflow-hidden" - /> - ) : undefined)} - </ul> - ) -} - -export default Slider \ No newline at end of file diff --git a/components/clinic/components/about/images/Images.js b/components/clinic/components/about/images/Images.js new file mode 100644 index 0000000..82dae44 --- /dev/null +++ b/components/clinic/components/about/images/Images.js @@ -0,0 +1,30 @@ +import List from './List'; +import Slider from './Slider'; +import Image from 'next/image'; +import CustomLoading from '@/app/component/loading/Custom'; + +function Images({ data, loading }) { + return ( + <div + className=' + flex flex-col md:flex-row items-center mb-[8px] justify-center w-full + gap-[12px] md:gap-[18px] lg:gap-[24px] overflow-hidden + '> + <div className='w-full'> + <CustomLoading loading={loading} width={600} height={400}> + <Image + className="rounded-[8px] overflow-hidden" + src={data.images_clinic[0]} + alt="img clinic" + height={432} + width={600} + /> + </CustomLoading> + </div> + <List data={data} loading={loading} /> + <Slider data={data} loading={loading} /> + </div> + ) +} + +export default Images \ No newline at end of file diff --git a/components/clinic/components/about/images/List.js b/components/clinic/components/about/images/List.js new file mode 100644 index 0000000..f657a8e --- /dev/null +++ b/components/clinic/components/about/images/List.js @@ -0,0 +1,55 @@ +import CustomLoading from '@/app/component/loading/Custom'; +import Image from 'next/image'; + +function List({ data, loading }) { + return ( + <div className="hidden w-full md:grid grid-cols-2 gap-[16px] lg:gap-[24px]"> + <div className='w-full'> + <CustomLoading loading={loading} width='full' height={190}> + <Image + className="rounded-[8px] overflow-hidden" + src={data.images_clinic[1]} + alt="img clinic" + height={204} + width={288} + /> + </CustomLoading> + </div> + <div className='w-full'> + <CustomLoading loading={loading} width='full' height={190}> + <Image + className="rounded-[8px] overflow-hidden" + src={data.images_clinic[2]} + alt="img clinic" + height={204} + width={288} + /> + </CustomLoading> + </div> + <div className='w-full'> + <CustomLoading loading={loading} width='full' height={190}> + <Image + className="rounded-[8px] overflow-hidden" + src={data.images_clinic[3]} + alt="img clinic" + height={204} + width={288} + /> + </CustomLoading> + </div> + <div className='w-full'> + <CustomLoading loading={loading} width='full' height={190}> + <Image + className="rounded-[8px] overflow-hidden" + src={data.images_clinic[4]} + alt="img clinic" + height={204} + width={288} + /> + </CustomLoading> + </div> + </div> + ) +} + +export default List \ No newline at end of file diff --git a/components/clinic/components/about/images/Slider.js b/components/clinic/components/about/images/Slider.js new file mode 100644 index 0000000..d57d2b9 --- /dev/null +++ b/components/clinic/components/about/images/Slider.js @@ -0,0 +1,24 @@ +import CustomLoading from "@/app/component/loading/Custom" +import Image from "next/image" + +function Slider({ data, loading }) { + return ( + <ul className="flex md:hidden gap-2 w-full justify-start items-center overflow-auto hidden-scroll"> + {[...data.images_clinic, ...data.images_clinic].map((item, idx) => + idx !== 0 ? ( + <CustomLoading width={90} height={90} loading={loading}> + <Image + key={idx} + src={item} + width={90} + height={90} + alt="image clinic" + className="min-w-[90px] min-h-[90px] object-cover rounded-[8px] overflow-hidden" + /> + </CustomLoading> + ) : undefined)} + </ul> + ) +} + +export default Slider \ No newline at end of file diff --git a/components/clinic/components/about/index.js b/components/clinic/components/about/index.js index afbb4e0..115612c 100644 --- a/components/clinic/components/about/index.js +++ b/components/clinic/components/about/index.js @@ -2,34 +2,37 @@ import { useState } from "react"; import ListBime from "./ListBime"; import Services from "./Services"; -import Images from "./iamges/Images"; +import Images from "./images/Images"; import { Button } from "@mui/material"; import Specialties from "./Specialties"; import ContentDetail from "./ContentDetail"; +import MultilineLoading from "@/app/component/loading/Multiline"; -function About({ data }) { +function About({ data, loading }) { const [isMore, setIsMore] = useState(false); return ( <div className="opacity-page transition-all duration-500"> - <Images data={data} /> - <ContentDetail head='کلینیک تخصصی و فوق تخصصی نیکان'> + <Images data={data} loading={loading} /> + <ContentDetail loading={loading} head='کلینیک تخصصی و فوق تخصصی نیکان'> <div className="flex flex-col items-center justify-center"> - <p - className={` + <MultilineLoading line={10} loading={loading} width='full' height={18}> + <p + className={` text-[#525252] text-[16px] font-normal leading-[20px] sm:leading-[24px] md:leading-[28px] lg:leading-[32px] overflow-hidden relative after:absolute after:right-0 after:bottom-0 after:h-[80px] after:shadow-xl after:w-full transition-all duration-500 ${isMore ? - 'after:bg-transparent max-h-screen' : - 'after:bg-[linear-gradient(transparent,#FAFAFA)] max-h-[200px]' - } + 'after:bg-transparent max-h-screen' : + 'after:bg-[linear-gradient(transparent,#FAFAFA)] max-h-[200px]' + } `} - dangerouslySetInnerHTML={{ __html: data.caption }} - ></p> + dangerouslySetInnerHTML={{ __html: data.caption }} + ></p> + </MultilineLoading> <Button - className="!text-[#F17732] !text-[14px] !font-light !p-2" + className={`${loading && '!hidden'} !text-[#F17732] !text-[14px] !font-light !p-2`} onClick={() => setIsMore(!isMore)} variant="text" > @@ -38,13 +41,13 @@ function About({ data }) { </div> </ContentDetail> <ContentDetail head='بیمه های طرف قرارداد'> - <ListBime data={data} /> + <ListBime loading={loading} data={data} /> </ContentDetail> <ContentDetail head='تخصص ها'> - <Specialties data={data} /> + <Specialties loading={loading} data={data} /> </ContentDetail> <ContentDetail head='خدمات'> - <Services data={data} /> + <Services loading={loading} data={data} /> </ContentDetail> </div> ) diff --git a/components/clinic/components/contact/ContentDetail.js b/components/clinic/components/contact/ContentDetail.js index 4576eaa..1332c21 100644 --- a/components/clinic/components/contact/ContentDetail.js +++ b/components/clinic/components/contact/ContentDetail.js @@ -1,8 +1,14 @@ -function ContentDetail({ head, detail }) { +import TextLoading from "@/app/component/loading/Text"; + +function ContentDetail({ head, detail, loading }) { return ( <li className="flex flex-col items-start justify-center gap-4"> - <p className="text-[#525252] text-[14px] sm:text-[16px] md:text-[18px] lg:text-[20px] font-bold">{head}</p> - <p className="text-[14px] md:text-[16px] text-[#525252]">{detail}</p> + <TextLoading width={100} height={18} loading={loading}> + <p className="text-[#525252] text-[14px] sm:text-[16px] md:text-[18px] lg:text-[20px] font-bold">{head}</p> + </TextLoading> + <TextLoading width={160} height={18} loading={loading}> + <p className="text-[14px] md:text-[16px] text-[#525252]">{detail}</p> + </TextLoading> </li> ) } diff --git a/components/clinic/components/contact/Detail.js b/components/clinic/components/contact/Detail.js index 2771181..5225327 100644 --- a/components/clinic/components/contact/Detail.js +++ b/components/clinic/components/contact/Detail.js @@ -1,22 +1,26 @@ import ContentDetail from "./ContentDetail" -function Detail({ data }) { +function Detail({ data, loading }) { return ( <ul className="flex flex-col items-start justify-start gap-[16px]"> <ContentDetail head='روزهای کاری: ' + loading={loading} detail={`ساعت کاری: ${data.hours_of_work}`} /> <ContentDetail head='تلفن: ' + loading={loading} detail={`${data.phone_number_1} ${data.phone_number_2}`} /> <ContentDetail head='ایمیل:' + loading={loading} detail={data.email} /> <ContentDetail head='آدرس: ' + loading={loading} detail={data.location} /> </ul> diff --git a/components/clinic/components/contact/index.js b/components/clinic/components/contact/index.js index 24611ae..6692e78 100644 --- a/components/clinic/components/contact/index.js +++ b/components/clinic/components/contact/index.js @@ -5,8 +5,9 @@ import { Button } from "@mui/material"; import Detail from "./Detail"; import RoutingC from "@/components/icons/RoutingC"; import ModalOpenLocation from "@/app/component/openLocation"; +import CustomLoading from "@/app/component/loading/Custom"; -function Contact({ data }) { +function Contact({ data, loading }) { const [open, setOpen] = useState(false); const handleOpen = () => setOpen(true); @@ -21,7 +22,7 @@ function Contact({ data }) { " > <div className="flex items-end justify-between"> - <Detail data={data} /> + <Detail data={data} loading={loading} /> <ModalOpenLocation open={open} setOpen={setOpen} @@ -40,23 +41,25 @@ function Contact({ data }) { <div className="w-full relative h-[460px] mt-[24px]" > - <iframe - src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d83998.96777841153!2d2.264635095144491!3d48.85882549249809!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x47e66e1f06e2b70f%3A0x40b82c3688c9460!2sParis%2C%20France!5e0!3m2!1sen!2snl!4v1723498499341!5m2!1sen!2snl" - className='w-full h-full rounded-lg' - loading="lazy" - ></iframe> - <ModalOpenLocation - open={open} - setOpen={setOpen} - handleClose={handleClose} - > - <Button - className="!flex md:!hidden !p-2 !absolute !left-3 !bottom-3 !rounded-full !border !border-[#5559CE] !bg-[#5559CE] !shadow-[0px_1px_24.8px_0px_rgba(69,_69,_69,_0.54)]" - onClick={handleOpen} + <CustomLoading width='full' height={400} loading={loading}> + <iframe + src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d83998.96777841153!2d2.264635095144491!3d48.85882549249809!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x47e66e1f06e2b70f%3A0x40b82c3688c9460!2sParis%2C%20France!5e0!3m2!1sen!2snl!4v1723498499341!5m2!1sen!2snl" + className='w-full h-full rounded-lg' + loading="lazy" + ></iframe> + <ModalOpenLocation + open={open} + setOpen={setOpen} + handleClose={handleClose} > - <RoutingWhiteC /> - </Button> - </ModalOpenLocation> + <Button + className="!flex md:!hidden !p-2 !absolute !left-3 !bottom-3 !rounded-full !border !border-[#5559CE] !bg-[#5559CE] !shadow-[0px_1px_24.8px_0px_rgba(69,_69,_69,_0.54)]" + onClick={handleOpen} + > + <RoutingWhiteC /> + </Button> + </ModalOpenLocation> + </CustomLoading> </div> </div> ) diff --git a/components/clinic/components/doctors/List.js b/components/clinic/components/doctors/List.js index 5e8fb14..0dae8c8 100644 --- a/components/clinic/components/doctors/List.js +++ b/components/clinic/components/doctors/List.js @@ -1,7 +1,7 @@ import ItemDoctor from '@/app/component/ItemDoctor'; import Pagination from '@/app/component/Pagination'; -function List({ doctors }) { +function List({ doctors, loading }) { return ( <> <ul className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 mt-[40px] gap-[16px] md:gap-[20px] lg:gap-[24px]"> @@ -9,6 +9,7 @@ function List({ doctors }) { <ItemDoctor key={doctor.id} doctor={doctor} + loading={loading} /> ))} </ul> diff --git a/components/clinic/components/doctors/index.js b/components/clinic/components/doctors/index.js index d5626d0..07afba7 100644 --- a/components/clinic/components/doctors/index.js +++ b/components/clinic/components/doctors/index.js @@ -1,11 +1,11 @@ import List from "./List" import SearchBar from "./SearchBar" -function Doctors({ doctors }) { +function Doctors({ doctors, loading }) { return ( <div> <SearchBar /> - <List doctors={doctors} /> + <List loading={loading} doctors={doctors} /> </div> ) } diff --git a/components/clinic/index.js b/components/clinic/index.js index a85ed0c..9c034ae 100644 --- a/components/clinic/index.js +++ b/components/clinic/index.js @@ -1,5 +1,6 @@ 'use client'; -import { useState } from 'react'; + +import { useEffect, useState } from 'react'; import About from './components/about'; import Contact from './components/contact'; @@ -11,14 +12,21 @@ const listTab = ['درباره کلینیک', 'اطلاعات تماس', 'پزش function ClinicPage({ data, doctors }) { const [value, setValue] = useState(0); + const [loading, setLoading] = useState(true); const handleChange = (event, newValue) => setValue(newValue); const Components = [ - <About data={data} />, - <Contact data={data} />, - <Doctors doctors={doctors} /> + <About data={data} loading={loading} />, + <Contact data={data} loading={loading} />, + <Doctors doctors={doctors} loading={loading} /> ]; + useEffect(() => { + setTimeout(() => { + setLoading(false); + }, 2000); + }, []); + return ( <div className="pt-[40px] sm:pt-[70px] md:pt-[100px] lg:pt-[136px] mt-[40px] padding-responsive"> <Tabs diff --git a/components/clinics/index.js b/components/clinics/index.js index 80a6c78..b4a8df0 100644 --- a/components/clinics/index.js +++ b/components/clinics/index.js @@ -1,9 +1,20 @@ -import HeadPageList from "@/app/component/head"; +'use client'; + +import { useEffect, useState } from "react"; + import List from "./list"; import SearchBar from "./head/SearchBar"; +import HeadPageList from "@/app/component/head"; function ClinicsPage() { + const [loading, setLoading] = useState(true); + + useEffect(() => { + setTimeout(() => { + setLoading(false); + }, 2000); + }, []); return ( <div> @@ -13,7 +24,7 @@ function ClinicsPage() { > <SearchBar /> </HeadPageList> - <List /> + <List loading={loading} /> </div> ) } diff --git a/components/clinics/list/ItemClinic.js b/components/clinics/list/ItemClinic.js index 34b35c5..f8b13c1 100644 --- a/components/clinics/list/ItemClinic.js +++ b/components/clinics/list/ItemClinic.js @@ -1,3 +1,5 @@ +import CircularLoading from "@/app/component/loading/Circular" +import TextLoading from "@/app/component/loading/Text" import ArrowLeftD from "@/components/icons/ArrowLeftD" import ClockClinic from "@/components/icons/ClockClinic" import LocationClinic from "@/components/icons/LocationClinic" @@ -5,36 +7,47 @@ import { Button } from "@mui/material" import Image from "next/image" import Link from "next/link" -function ItemClinic({ data }) { +function ItemClinic({ data, loading }) { return ( <li className="p-4 relative bg-[#FFF] border border-solid border-[#EFEFEF] rounded-[8px]"> <div className="flex items-center justify-start gap-2"> - <Image - width={60} - height={60} - src={data.img} - alt="img clinic" - /> + <CircularLoading loading={loading} width={60} height={60}> + <Image + width={60} + height={60} + src={data.img} + alt="img clinic" + /> + </CircularLoading> <div className="flex flex-col items-start justify-center gap-2"> - <p className="text-[#3B3B3B] text-[14px] font-bold">{data.title}</p> - <p className="text-[#7E7E7E] text-[14px] font-normal">{data.doctors} پزشک</p> + <TextLoading loading={loading} width={100} height={18}> + <p className="text-[#3B3B3B] text-[14px] font-bold">{data.title}</p> + </TextLoading> + <TextLoading loading={loading} width={60} height={18}> + <p className="text-[#7E7E7E] text-[14px] font-normal">{data.doctors} پزشک</p> + </TextLoading> </div> </div> <div className="flex flex-col items-start mt-4 gap-4 mb-[14px]"> <div className="flex items-start justify-start gap-0.5"> <LocationClinic /> - <p className="text-[#7E7E7E] text-[12px] font-normal">{data.location}</p> + <TextLoading loading={loading} width={150} height={18}> + <p className="text-[#7E7E7E] text-[12px] font-normal">{data.location}</p> + </TextLoading> </div> <div className="flex items-start justify-start gap-0.5 ml-[64px]"> <ClockClinic /> - <p className="text-[#7E7E7E] text-[12px] font-normal">ساعت کاری: {data.hours_of_work}</p> + <TextLoading loading={loading} width={120} height={18}> + <p className="text-[#7E7E7E] text-[12px] font-normal">ساعت کاری: {data.hours_of_work}</p> + </TextLoading> </div> </div> {/* Arrow */} - <Link href={`/clinic/${data.id}`}> + <Link href={loading ? '#' : `/clinic/${data.id}`}> <Button - className='!p-[14px] !bg-[#5559CE] !absolute !left-4 !bottom-4 !rounded-full !w-fit' + className={`${loading ? '!bg-[#E7E7E7]' : '!bg-[#5559CE]'} !p-[14px] !absolute !left-4 !bottom-4 !rounded-full !w-fit`} + disabled={loading} > <ArrowLeftD /> </Button> diff --git a/components/clinics/list/index.js b/components/clinics/list/index.js index 9036d61..52701d1 100644 --- a/components/clinics/list/index.js +++ b/components/clinics/list/index.js @@ -3,9 +3,9 @@ import clinics from '@/data/clinics.json'; import ItemClinic from "./ItemClinic"; import Pagination from "@/app/component/Pagination"; -function List() { +function List({ loading }) { - const listPage = ['کلینیک ها', 'اهواز'] + const listPage = ['کلینیک ها', 'اهواز']; return ( <div className="padding-responsive pt-[20px]"> @@ -18,6 +18,7 @@ function List() { <ItemClinic data={item} key={item.id} + loading={loading} /> ))} </ul> diff --git a/components/dashboard/index.js b/components/dashboard/index.js index 8745b84..3eae3ee 100644 --- a/components/dashboard/index.js +++ b/components/dashboard/index.js @@ -1,4 +1,3 @@ -import React from 'react' import Layout from '../layout' function DashboardPage({ user, children, value, setValue, isOpenSide, setIsOpenSide }) { diff --git a/components/dashboard/userAccount/ContentTabs.js b/components/dashboard/userAccount/ContentTabs.js index f9d72cf..edc0294 100644 --- a/components/dashboard/userAccount/ContentTabs.js +++ b/components/dashboard/userAccount/ContentTabs.js @@ -1,6 +1,6 @@ 'use client' -import { useState } from "react"; +import { useEffect, useState } from "react"; // Tabs import Turns from "./tabs/turns"; @@ -17,15 +17,23 @@ const listTab = ['حساب کاربری', 'نوبت های من', 'تراکنش function ContentTabs({ user, value, setValue, isOpenSide, setIsOpenSide }) { + const [loading, setLoading] = useState(true); const [isTurnsDetails, setIsTurnsDetails] = useState(false); const handleChange = (event, newValue) => setValue(newValue); + useEffect(() => { + setTimeout(() => { + setLoading(true); + }, 2000); + }, []); + + const components = [ <DetailUser user={user} />, - <Turns user={user} setIsTurnsDetails={setIsTurnsDetails} />, - <Transactions user={user} />, - <Comments user={user} />, - <Messages user={user} /> + <Turns user={user} loading={loading} setIsTurnsDetails={setIsTurnsDetails} />, + <Transactions user={user} loading={loading} />, + <Comments user={user} loading={loading} />, + <Messages user={user} loading={loading} /> ]; return ( @@ -43,7 +51,7 @@ function ContentTabs({ user, value, setValue, isOpenSide, setIsOpenSide }) { <p className="text-[#525252] text-[14px] font-bold">{isTurnsDetails ? 'جزئیات نوبت ' : listTab[value]}</p> </Button> {isTurnsDetails ? - <IsTurnsDetails user={user} setIsTurnsDetails={setIsTurnsDetails} /> : ( + <IsTurnsDetails loading={loading} user={user} setIsTurnsDetails={setIsTurnsDetails} /> : ( <> <div className='!hidden md:!flex !w-full'> <Tabs diff --git a/components/dashboard/userAccount/tabs/comments/Comment.js b/components/dashboard/userAccount/tabs/comments/Comment.js index 468ed48..5d68d0d 100644 --- a/components/dashboard/userAccount/tabs/comments/Comment.js +++ b/components/dashboard/userAccount/tabs/comments/Comment.js @@ -2,42 +2,60 @@ import CalndarD from "@/components/icons/CalndarD" import { Rating } from "@mui/material" import Image from "next/image" import ModalDeleteComment from "./modal" +import CircularLoading from "@/app/component/loading/Circular" +import TextLoading from "@/app/component/loading/Text" +import CustomLoading from "@/app/component/loading/Custom" +import MultilineLoading from "@/app/component/loading/Multiline" -function Comment({ data }) { +function Comment({ data, loading }) { return ( <li className="flex flex-col gap-[8px] w-full"> <div className="flex items-start justify-between w-full"> <div className="flex items-center justify-start gap-[8px] md:gap-[12px] lg:gap-[16px]"> - <Image - className="w-[48px] sm:w-[61px] md:w-[75px] lg:w-[88px] h-[48px] sm:h-[61px] md:h-[75px] lg:h-[88px]" - src={data.profile} - alt="profile" - height={87} - width={87} - /> + <CircularLoading loading={loading} width={87} height={87}> + <Image + className="w-[48px] sm:w-[61px] md:w-[75px] lg:w-[88px] h-[48px] sm:h-[61px] md:h-[75px] lg:h-[88px]" + src={data.profile} + alt="profile" + height={87} + width={87} + /> + </CircularLoading> <div className="flex flex-col items-start justify-center gap-[8px] md:gap-[12px] lg:gap-[16px]"> - <p className="text-[#3B3B3B] text-[12px] md:text-[14px] lg:text-[16px] font-bold">{data.name_doctor}</p> - <p className="text-[#525252] text-[12px] md:text-[14px] font-medium">تخصص: {data.expertise}</p> + <TextLoading loading={loading} width={105} height={18}> + <p className="text-[#3B3B3B] text-[12px] md:text-[14px] lg:text-[16px] font-bold">{data.name_doctor}</p> + </TextLoading> + <TextLoading loading={loading} width={65} height={18}> + <p className="text-[#525252] text-[12px] md:text-[14px] font-medium">تخصص: {data.expertise}</p> + </TextLoading> </div> </div> - <ModalDeleteComment /> + <CustomLoading loading={loading} width={90} height={30}> + <ModalDeleteComment /> + </CustomLoading> </div> - <Rating - defaultValue={data.stars.value} - className="!mt-[4px] md:!mt-[6px] lg:!mt-[8px]" - sx={{ - '& .MuiSvgIcon-root': { - width: '16px', - height: '16px' - } - }} - /> - <p className="text-[#525252] mt-[4px] md:mt-[2px] lg:mt-0 text-[14px] font-normal leading-[28px] md:leading-[30px] lg:leading-[33px]">{data.comment}</p> + <CustomLoading loading={loading} width={130} height={18}> + <Rating + defaultValue={data.stars.value} + className="!mt-[4px] md:!mt-[6px] lg:!mt-[8px]" + sx={{ + '& .MuiSvgIcon-root': { + width: '16px', + height: '16px' + } + }} + /> + </CustomLoading> + <MultilineLoading loading={loading} width='full' height={18} line={2}> + <p className="text-[#525252] mt-[4px] md:mt-[2px] lg:mt-0 text-[14px] font-normal leading-[28px] md:leading-[30px] lg:leading-[33px]">{data.comment}</p> + </MultilineLoading> <div className="flex items-center justify-start gap-[8px]"> <div className="w-[20px] h-[20px] sm:w-[22px] sm:h-[22px] lg:w-[24px] lg:h-[24px]"> <CalndarD /> </div> - <p className="text-[#7E7E7E] text-[12px] font-normal">{data.date}</p> + <TextLoading width={90} height={18} loading={loading}> + <p className="text-[#7E7E7E] text-[12px] font-normal">{data.date}</p> + </TextLoading> </div> <span className="w-full block h-px bg-[#EFEFEF] mt-0 md:mt-[4px] mt-[8px]"></span> </li> diff --git a/components/dashboard/userAccount/tabs/comments/index.js b/components/dashboard/userAccount/tabs/comments/index.js index 7a675c2..719cbf6 100644 --- a/components/dashboard/userAccount/tabs/comments/index.js +++ b/components/dashboard/userAccount/tabs/comments/index.js @@ -1,12 +1,13 @@ import Comment from "./Comment" -function Comments({ user }) { +function Comments({ user, loading }) { return ( <ul className="flex opacity-page flex-col items-start justify-start gap-[24px] md:gap-[22px] lg:gap-[20px]"> {user.comments.map((item, idx) => ( <Comment key={idx} data={item} + loading={loading} /> ))} </ul> diff --git a/components/dashboard/userAccount/tabs/messages/Message.js b/components/dashboard/userAccount/tabs/messages/Message.js index 9d56b71..423cece 100644 --- a/components/dashboard/userAccount/tabs/messages/Message.js +++ b/components/dashboard/userAccount/tabs/messages/Message.js @@ -1,23 +1,31 @@ +import MultilineLoading from '@/app/component/loading/Multiline' +import TextLoading from '@/app/component/loading/Text' import CalndarD from '@/components/icons/CalndarD' import MessageNotifd from '@/components/icons/MessageNotifD' import React from 'react' -function Message({ data }) { +function Message({ data, loading }) { return ( <li> <div className="flex items-center justify-start gap-[8px]"> <div className="p-[6px] rounded-full bg-[#F17732]"> <MessageNotifd /> </div> - <p className="text-[#3B3B3B] text-[12px] md:text-[14px] lg:text-[16px] font-bold">عنوان پیام</p> + <TextLoading width={60} height={18} loading={loading}> + <p className="text-[#3B3B3B] text-[12px] md:text-[14px] lg:text-[16px] font-bold">عنوان پیام</p> + </TextLoading> </div> <div className='mr-0 lg:mr-[41px]'> - <p className='text-[#525252] text-[12px] md:text-[14px] font-normal leading-[28px] md:leading-[30px] lg:leading-[33px]'>{data.text}</p> + <MultilineLoading width='full' height={18} loading={loading} line={2}> + <p className='text-[#525252] text-[12px] md:text-[14px] font-normal leading-[28px] md:leading-[30px] lg:leading-[33px]'>{data.text}</p> + </MultilineLoading> <div className='flex items-center justify-start gap-[8px] mt-[8px] md:mt-[10px] lg:mt-[12px]'> <div className='max-w-[20px] max-h-[20px] md:max-w-[22px] md:max-h-[22px] lg:max-w-[24px] lg:max-h-[24px]'> <CalndarD /> </div> - <p className='text-[#7E7E7E] text-[12px] font-normal'>{data.date}</p> + <TextLoading width={60} height={18} loading={loading}> + <p className='text-[#7E7E7E] text-[12px] font-normal'>{data.date}</p> + </TextLoading> </div> </div> <span className='block bg-[#EFEFEF] h-px w-full mt-[12px]'></span> diff --git a/components/dashboard/userAccount/tabs/messages/index.js b/components/dashboard/userAccount/tabs/messages/index.js index 9958956..bf3708b 100644 --- a/components/dashboard/userAccount/tabs/messages/index.js +++ b/components/dashboard/userAccount/tabs/messages/index.js @@ -1,12 +1,13 @@ import Message from "./Message"; -function Messages({ user }) { +function Messages({ user, loading }) { return ( <ul className="flex opacity-page flex-col gap-[24px] md:gap-[20px] lg:gap-[16px]"> {user.messages.map((item, idx) => ( <Message key={idx} data={item} + loading={loading} /> ))} </ul> diff --git a/components/dashboard/userAccount/tabs/transactions/Card.js b/components/dashboard/userAccount/tabs/transactions/Card.js index 87c3de6..70b11c2 100644 --- a/components/dashboard/userAccount/tabs/transactions/Card.js +++ b/components/dashboard/userAccount/tabs/transactions/Card.js @@ -1,49 +1,73 @@ +import CircularLoading from "@/app/component/loading/Circular" +import TextLoading from "@/app/component/loading/Text" import Image from "next/image" -function Card({ data }) { +function Card({ data, loading }) { return ( <li className="p-[12px] shadow-[0px_1px_24.8px_0px_rgba(204,_204,_204,_0.18)] bg-[#FFF] rounded-[8px]"> <div className="flex items-center justify-between w-full"> <div className="flex items-center justify-start gap-[8px]"> - <Image - src={data.image} - alt="profile" - height={32} - width={32} - /> - <p className="text-[#616161] text-[14px] font-medium">{data.name}</p> + <CircularLoading width={32} height={32} loading={loading}> + <Image + src={data.image} + alt="profile" + height={32} + width={32} + /> + </CircularLoading> + <TextLoading width={90} height={18} loading={loading}> + <p className="text-[#616161] text-[14px] font-medium">{data.name}</p> + </TextLoading> </div> - <div - className={` + <TextLoading loading={loading} width={95} height={25}> + <div + className={` w-[100px] p-[4px] rounded-[4px] text-center text-[14px] font-medium cursor-pointer select-none ${data.status === 'success' ? 'bg-[#E8FADD] text-[#75E22E]' : - data.status === 'pending' ? 'bg-[#FFF3DD] text-[#FDBA35]' : 'bg-[#FFE3E2] text-[#FF5450]'} + data.status === 'pending' ? 'bg-[#FFF3DD] text-[#FDBA35]' : 'bg-[#FFE3E2] text-[#FF5450]'} `} - variant='text' - > - {data.status === 'success' ? 'پرداخت شده' : - data.status === 'pending' ? 'در انتظار' : 'پرداخت نشده'} - </div> + variant='text' + > + {data.status === 'success' ? 'پرداخت شده' : + data.status === 'pending' ? 'در انتظار' : 'پرداخت نشده'} + </div> + </TextLoading> </div> <ul className="flex flex-col mt-[16px]"> <li className="flex items-center justify-between gap-[12px]"> - <p className="text-[#7E7E7E] text-[14px] font-normal">شناسه:</p> - <p className="text-[#616161] text-[14px] font-medium">{data.id}</p> + <TextLoading loading={loading} width={60} height={18}> + <p className="text-[#7E7E7E] text-[14px] font-normal">شناسه:</p> + </TextLoading> + <TextLoading loading={loading} width={90} height={18}> + <p className="text-[#616161] text-[14px] font-medium">{data.id}</p> + </TextLoading> </li> <span className="block h-px w-[calc(100%-20px)] mx-auto bg-[#EFEFEF] my-[8px]"></span> <li className="flex items-center justify-between gap-[12px]"> - <p className="text-[#7E7E7E] text-[14px] font-normal">تاریخ نوبت:</p> - <p className="text-[#616161] text-[14px] font-medium">{data.date}</p> + <TextLoading loading={loading} width={90} height={18}> + <p className="text-[#7E7E7E] text-[14px] font-normal">تاریخ نوبت:</p> + </TextLoading> + <TextLoading loading={loading} width={60} height={18}> + <p className="text-[#616161] text-[14px] font-medium">{data.date}</p> + </TextLoading> </li> <span className="block h-px w-[calc(100%-20px)] mx-auto bg-[#EFEFEF] my-[8px]"></span> <li className="flex items-center justify-between gap-[12px]"> - <p className="text-[#7E7E7E] text-[14px] font-normal">ساعت نوبت:</p> - <p className="text-[#616161] text-[14px] font-medium">{data.time}</p> + <TextLoading loading={loading} width={80} height={18}> + <p className="text-[#7E7E7E] text-[14px] font-normal">ساعت نوبت:</p> + </TextLoading> + <TextLoading loading={loading} width={80} height={18}> + <p className="text-[#616161] text-[14px] font-medium">{data.time}</p> + </TextLoading> </li> <span className="block h-px w-[calc(100%-20px)] mx-auto bg-[#EFEFEF] my-[8px]"></span> <li className="flex items-center justify-between gap-[12px]"> - <p className="text-[#7E7E7E] text-[14px] font-normal">مبلغ پیش پرداخت:</p> - <p className="text-[#616161] text-[14px] font-medium">{data.amount} تومان</p> + <TextLoading loading={loading} width={110} height={18}> + <p className="text-[#7E7E7E] text-[14px] font-normal">مبلغ پیش پرداخت:</p> + </TextLoading> + <TextLoading loading={loading} width={40} height={18}> + <p className="text-[#616161] text-[14px] font-medium">{data.amount} تومان</p> + </TextLoading> </li> </ul> </li> diff --git a/components/dashboard/userAccount/tabs/transactions/List.js b/components/dashboard/userAccount/tabs/transactions/List.js index 283c7e3..4dfcf90 100644 --- a/components/dashboard/userAccount/tabs/transactions/List.js +++ b/components/dashboard/userAccount/tabs/transactions/List.js @@ -2,8 +2,11 @@ import CustomTable from "@/app/component/CustomTable"; import { TableCell, TableRow } from "@mui/material"; import Image from "next/image"; import Card from "./Card"; +import TextLoading from "@/app/component/loading/Text"; +import CustomLoading from "@/app/component/loading/Custom"; +import CircularLoading from "@/app/component/loading/Circular"; -function List({ user }) { +function List({ user, loading }) { const tableHead = ['ردیف', 'شناسه', 'نام پزشک', 'تاریخ', 'ساعت', 'مبلغ (تومان)', 'وضعیت'] const centerTable = [0, 4, 5]; @@ -20,34 +23,60 @@ function List({ user }) { key={idx} className='!border-0 !border-b !border-[#DBDBDB]' > - <TableCell className='!pr-[18px] !text-nowrap' align="center">{idx + 1}</TableCell> - <TableCell className='!text-start !pr-[18px] !text-nowrap' align="right">{row.id}</TableCell> + <TableCell className='!pr-[18px] !text-nowrap' align="center"> + <TextLoading width={15} height={18} loading={loading}> + {idx + 1} + </TextLoading> + </TableCell> + <TableCell className='!text-start !pr-[18px] !text-nowrap' align="right"> + <TextLoading width={30} height={18} loading={loading}> + {row.id} + </TextLoading> + </TableCell> <TableCell className='!pr-[18px] !text-nowrap' component="th" scope="row"> <div className='flex items-center justify-start gap-[8px] !text-nowrap'> - <Image - src={row.image} - alt='doctor' - height={32} - width={32} - /> - {row.name} + <CircularLoading width={32} height={32} loading={loading}> + <Image + src={row.image} + alt='doctor' + height={32} + width={32} + /> + </CircularLoading> + <TextLoading width={40} height={18} loading={loading}> + {row.name} + </TextLoading> </div> </TableCell> - <TableCell className='!text-start !pr-[18px] !text-nowrap' align="right">{row.date}</TableCell> - <TableCell className='!text-center !pr-[18px] !text-nowrap' align="right">{row.time}</TableCell> - <TableCell className='!text-center !pr-[18px] !text-nowrap' align="right">{row.amount}</TableCell> + <TableCell className='!text-start !pr-[18px] !text-nowrap' align="right"> + <TextLoading width={50} height={18} loading={loading}> + {row.date} + </TextLoading> + </TableCell> + <TableCell className='!text-center !pr-[18px] !text-nowrap' align="right"> + <TextLoading width={50} height={18} loading={loading}> + {row.time} + </TextLoading> + </TableCell> + <TableCell className='!text-center !pr-[18px] !text-nowrap' align="right"> + <TextLoading width={50} height={18} loading={loading}> + {row.amount} + </TextLoading> + </TableCell> <TableCell className='!pr-[18px] !text-nowrap' align="right"> - <div - className={` + <CustomLoading width={80} height={22} loading={loading}> + <div + className={` w-[124px] py-[4px] px-[4px] rounded-[4px] text-center text-[16px] font-medium cursor-pointer select-none ${row.status === 'success' ? 'bg-[#E8FADD] text-[#75E22E]' : - row.status === 'pending' ? 'bg-[#FFF3DD] text-[#FDBA35]' : 'bg-[#FFE3E2] text-[#FF5450]'} + row.status === 'pending' ? 'bg-[#FFF3DD] text-[#FDBA35]' : 'bg-[#FFE3E2] text-[#FF5450]'} `} - variant='text' - > - {row.status === 'success' ? 'پرداخت شده' : - row.status === 'pending' ? 'در انتظار' : 'پرداخت نشده'} - </div> + variant='text' + > + {row.status === 'success' ? 'پرداخت شده' : + row.status === 'pending' ? 'در انتظار' : 'پرداخت نشده'} + </div> + </CustomLoading> </TableCell> </TableRow> ))} @@ -58,6 +87,7 @@ function List({ user }) { <Card key={idx} data={row} + loading={loading} /> ))} </ul> diff --git a/components/dashboard/userAccount/tabs/transactions/index.js b/components/dashboard/userAccount/tabs/transactions/index.js index b7c00a4..1118f5f 100644 --- a/components/dashboard/userAccount/tabs/transactions/index.js +++ b/components/dashboard/userAccount/tabs/transactions/index.js @@ -1,10 +1,10 @@ import List from "./List"; -function Transactions({ user }) { +function Transactions({ user, loading }) { return ( <div className="opacity-page"> <p className="text-[#3B3B3B] hidden md:block text-[16px] font-bold">تاریخچه تراکنش ها</p> - <List user={user} /> + <List user={user} loading={loading} /> </div> ) } diff --git a/components/dashboard/userAccount/tabs/turns/Card.js b/components/dashboard/userAccount/tabs/turns/Card.js index 8715295..fd2f92a 100644 --- a/components/dashboard/userAccount/tabs/turns/Card.js +++ b/components/dashboard/userAccount/tabs/turns/Card.js @@ -1,44 +1,64 @@ +import CircularLoading from "@/app/component/loading/Circular" +import TextLoading from "@/app/component/loading/Text" import ArrowLeftCardD from "@/components/icons/ArrowLeftCardD" import { Button } from "@mui/material" import Image from "next/image" -function Card({ data, setIsTurnsDetails }) { +function Card({ data, loading, setIsTurnsDetails }) { return ( <li className="shadow-[0px_1px_24.8px_0px_rgba(204,_204,_204,_0.18)] pb-[8px] bg-[#FFF] rounded-[8px]" > <div className="flex items-center justify-start gap-[8px] p-[12px]"> - <Image - width={32} - height={32} - alt="profile" - src={data.image} - /> + <CircularLoading width={32} height={32} loading={loading}> + <Image + width={32} + height={32} + alt="profile" + src={data.image} + /> + </CircularLoading> <div className="flex flex-col items-start justify-center gap-[8px]"> - <p className="text-[#616161] text-[14px] font-medium">{data.name}</p> - <p className="text-[#7E7E7E] text-[14px] font-normal">{data.expertise}</p> + <TextLoading loading={loading} width={65} height={18}> + <p className="text-[#616161] text-[14px] font-medium">{data.name}</p> + </TextLoading> + <TextLoading loading={loading} width={50} height={18}> + <p className="text-[#7E7E7E] text-[14px] font-normal">{data.expertise}</p> + </TextLoading> </div> </div> <ul className="w-full py-[8px] px-[12px] bg-[#FAFAFA] flex flex-col gap-[12px]"> <li className="flex items-center justify-between"> - <p className="text-[#7E7E7E] text-[14px] font-normal">تاریخ نوبت:</p> - <p className="text-[#525252] text-[14px] font-medium">{data.date}</p> + <TextLoading loading={loading} width={75} height={18}> + <p className="text-[#7E7E7E] text-[14px] font-normal">تاریخ نوبت:</p> + </TextLoading> + <TextLoading loading={loading} width={110} height={18}> + <p className="text-[#525252] text-[14px] font-medium">{data.date}</p> + </TextLoading> </li> <li className="flex items-center justify-between"> - <p className="text-[#7E7E7E] text-[14px] font-normal">ساعت نوبت:</p> - <p className="text-[#525252] text-[14px] font-medium">{data.time}</p> + <TextLoading loading={loading} width={65} height={18}> + <p className="text-[#7E7E7E] text-[14px] font-normal">ساعت نوبت:</p> + </TextLoading> + <TextLoading loading={loading} width={60} height={18}> + <p className="text-[#525252] text-[14px] font-medium">{data.time}</p> + </TextLoading> </li> </ul> <div className="mt-[12px] flex items-center justify-between px-[12px]"> - <p className="text-[#7E7E7E] text-[12px] font-normal">مبلغ پیش پرداخت: {data.amount} تومان</p> - <Button - className="!flex !p-1 !items-center !justify-end !gap-[2px]" - onClick={() => setIsTurnsDetails(true)} - variant="text" - > - مشاهده - <ArrowLeftCardD /> - </Button> + <TextLoading loading={loading} width={120} height={18}> + <p className="text-[#7E7E7E] text-[12px] font-normal">مبلغ پیش پرداخت: {data.amount} تومان</p> + </TextLoading> + <TextLoading loading={loading} width={80} height={25}> + <Button + className="!flex !p-1 !items-center !justify-end !gap-[2px]" + onClick={() => setIsTurnsDetails(true)} + variant="text" + > + مشاهده + <ArrowLeftCardD /> + </Button> + </TextLoading> </div> </li> ) diff --git a/components/dashboard/userAccount/tabs/turns/List.js b/components/dashboard/userAccount/tabs/turns/List.js index 4cedcf3..8d8af0c 100644 --- a/components/dashboard/userAccount/tabs/turns/List.js +++ b/components/dashboard/userAccount/tabs/turns/List.js @@ -3,13 +3,15 @@ import ArrowLeftBlueD from '@/components/icons/ArrowLeftBlueD' import { Button, TableCell, TableRow } from '@mui/material' import Image from 'next/image' import Card from './Card'; +import CircularLoading from '@/app/component/loading/Circular'; +import TextLoading from '@/app/component/loading/Text'; +import CustomLoading from '@/app/component/loading/Custom'; -function List({ user, setIsTurnsDetails }) { +function List({ user, loading, setIsTurnsDetails }) { const tableHead = ['ردیف', 'نام پزشک', 'تخصص', 'تاریخ', 'ساعت', 'مبلغ (تومان)', 'عملیات'] const centerTable = [0, 5]; - return ( <div className='!mt-[24px]'> <div className='hidden lg:block'> @@ -22,31 +24,57 @@ function List({ user, setIsTurnsDetails }) { key={idx} className='!border-0 !border-b !border-[#DBDBDB]' > - <TableCell className='!pr-[18px] !text-nowrap' align="center">{idx + 1}</TableCell> + <TableCell className='!pr-[18px] !text-nowrap' align="center"> + <TextLoading width={15} height={18} loading={loading}> + {idx + 1} + </TextLoading> + </TableCell> <TableCell className='!pr-[18px] !text-nowrap' component="th" scope="row"> <div className='flex items-center justify-start gap-[8px] !text-nowrap'> - <Image - src={row.image} - alt='doctor' - height={32} - width={32} - /> - {row.name} + <CircularLoading width={32} height={32} loading={loading}> + <Image + src={row.image} + alt='doctor' + height={32} + width={32} + /> + </CircularLoading> + <TextLoading width={40} height={18} loading={loading}> + {row.name} + </TextLoading> </div> </TableCell> - <TableCell className='!text-start !pr-[18px] !text-nowrap' align="right">{row.expertise}</TableCell> - <TableCell className='!text-start !pr-[18px] !text-nowrap' align="right">{row.date}</TableCell> - <TableCell className='!text-center !pr-[18px] !text-nowrap' align="right">{row.time}</TableCell> - <TableCell className='!text-center !pr-[18px] !text-nowrap' align="right">{row.amount}</TableCell> + <TableCell className='!text-start !pr-[18px] !text-nowrap' align="right"> + <TextLoading width={50} height={18} loading={loading}> + {row.expertise} + </TextLoading> + </TableCell> + <TableCell className='!text-start !pr-[18px] !text-nowrap' align="right"> + <TextLoading width={50} height={18} loading={loading}> + {row.date} + </TextLoading> + </TableCell> + <TableCell className='!text-center !pr-[18px] !text-nowrap' align="right"> + <TextLoading width={50} height={18} loading={loading}> + {row.time} + </TextLoading> + </TableCell> + <TableCell className='!text-center !pr-[18px] !text-nowrap' align="right"> + <TextLoading width={50} height={18} loading={loading}> + {row.amount} + </TextLoading> + </TableCell> <TableCell className='!pr-[18px] !text-nowrap' align="right"> - <Button - className='!flex !p-1 !items-center !justify-start !gap-[4px] !text-[14px] !font-bold !text-[#5559CE]' - onClick={() => setIsTurnsDetails(true)} - variant='text' - > - مشاهده جزئیات - <ArrowLeftBlueD /> - </Button> + <CustomLoading width={80} height={22} loading={loading}> + <Button + className='!flex !p-1 !items-center !justify-start !gap-[4px] !text-[14px] !font-bold !text-[#5559CE]' + onClick={() => setIsTurnsDetails(true)} + variant='text' + > + مشاهده جزئیات + <ArrowLeftBlueD /> + </Button> + </CustomLoading> </TableCell> </TableRow> ))} @@ -57,6 +85,7 @@ function List({ user, setIsTurnsDetails }) { <Card key={idx} data={item} + loading={loading} setIsTurnsDetails={setIsTurnsDetails} /> ))} diff --git a/components/dashboard/userAccount/tabs/turns/index.js b/components/dashboard/userAccount/tabs/turns/index.js index f34429a..d63a827 100644 --- a/components/dashboard/userAccount/tabs/turns/index.js +++ b/components/dashboard/userAccount/tabs/turns/index.js @@ -2,7 +2,7 @@ import { useState } from "react"; import Head from "./Head"; import List from "./List"; -function Turns({ user, setIsTurnsDetails }) { +function Turns({ user, setIsTurnsDetails, loading }) { const [value, setValue] = useState(0); const handleChange = (event, newValue) => setValue(newValue); @@ -15,7 +15,7 @@ function Turns({ user, setIsTurnsDetails }) { setValue={setValue} handleChange={handleChange} /> - <List user={user} setIsTurnsDetails={setIsTurnsDetails} /> + <List user={user} loading={loading} setIsTurnsDetails={setIsTurnsDetails} /> </div> ) } diff --git a/components/dashboard/userAccount/tabs/turns/isTurnsDetails/ButtonData.js b/components/dashboard/userAccount/tabs/turns/isTurnsDetails/ButtonData.js index cc96472..e388d8a 100644 --- a/components/dashboard/userAccount/tabs/turns/isTurnsDetails/ButtonData.js +++ b/components/dashboard/userAccount/tabs/turns/isTurnsDetails/ButtonData.js @@ -3,12 +3,13 @@ import ModalDeleteComment from "./modal" import EditTurnsD from "@/components/icons/EditTurnsD" import ArrowLeftD from "@/components/icons/ArrowLeftD" -function ButtonData() { +function ButtonData({ loading }) { return ( <div className="flex mt-[48px] md:mt-0 items-center justify-center md:justify-end gap-[16px] sm:gap-[16px] md:gap-[20px] lg:gap-[24px]"> - <ModalDeleteComment /> + <ModalDeleteComment loading={loading} /> <Button className="!rounded-[4px] !shadow-none !gap-[4px] !py-[6px] md:!py-[7px] lg:!py-[8px] !px-[12px]" + disabled={loading} variant="contained" > <EditTurnsD /> diff --git a/components/dashboard/userAccount/tabs/turns/isTurnsDetails/DetailLg.js b/components/dashboard/userAccount/tabs/turns/isTurnsDetails/DetailLg.js index 21edfc0..6cff72f 100644 --- a/components/dashboard/userAccount/tabs/turns/isTurnsDetails/DetailLg.js +++ b/components/dashboard/userAccount/tabs/turns/isTurnsDetails/DetailLg.js @@ -1,3 +1,5 @@ +import CircularLoading from '@/app/component/loading/Circular'; +import TextLoading from '@/app/component/loading/Text'; import CalendarD from '@/components/icons/CalendarD'; import CallD from '@/components/icons/CallD'; import ClockClinic from '@/components/icons/ClockClinic'; @@ -8,57 +10,75 @@ import { Button } from '@mui/material'; import Image from 'next/image' import React from 'react' -function DetailLg({ user }) { +function DetailLg({ user, loading }) { const data = user.turns[1]; return ( <div className='lg:mt-[18px] hidden md:block'> <div className='flex md:mt-[24px] lg:mt-0 items-center justify-start gap-[8px] md:gap-[12px] lg:gap-[16px]'> - <Image - width={95} - height={95} - alt='profile' - src={data.image} - className='w-[32px] h-[32px] sm:w-[53px] sm:h-[53px] md:w-[74px] md:h-[74px] lg:w-[95px] lg:h-[95px]' - /> + <CircularLoading width={95} height={95} loading={loading}> + <Image + width={95} + height={95} + alt='profile' + src={data.image} + className='w-[32px] h-[32px] sm:w-[53px] sm:h-[53px] md:w-[74px] md:h-[74px] lg:w-[95px] lg:h-[95px]' + /> + </CircularLoading> <div className='flex flex-col items-start justify-center gap-[20px]'> - <p className='text-[#3B3B3B] text-[14px] sm:text-[16px] md:text-[18px] lg:text-[20px] font-medium'>{data.name}</p> - <p className='text-[#616161] text-[14px] md:text-[15px] lg:text-[16px] font-medium'>تخصص: {data.expertise}</p> + <TextLoading loading={loading} width={70} height={18}> + <p className='text-[#3B3B3B] text-[14px] sm:text-[16px] md:text-[18px] lg:text-[20px] font-medium'>{data.name}</p> + </TextLoading> + <TextLoading loading={loading} width={80} height={18}> + <p className='text-[#616161] text-[14px] md:text-[15px] lg:text-[16px] font-medium'>تخصص: {data.expertise}</p> + </TextLoading> </div> </div> <ul className='flex mt-[16px] sm:mt-[21px] md:mt-[27px] lg:mt-[32px] mb-[24px] flex-col gap-[24px] items-start justify-start'> <li className='flex items-center justify-start flex-wrap gap-[16px] lg:gap-[56px]'> - <div className='flex items-start justify-start gap-[4px]'> - <CalendarD /> - <p className='text-[#616161] text-[14px] lg:text-[20px] font-medium'>تاریخ نوبت: <span className='text-[#2F2F2F] text-[14px] lg:text-[20px] font-bold'>{data.date_turn}</span></p> - </div> - <div className='flex items-start justify-start gap-[4px]'> - <ClockClinic /> - <p className='text-[#616161] text-[14px] lg:text-[20px] font-medium'>زمان نوبت: <span className='text-[#2F2F2F] text-[14px] lg:text-[20px] font-bold'>ساعت {data.time}</span></p> - </div> + <TextLoading loading={loading} width={100} height={20}> + <div className='flex items-start justify-start gap-[4px]'> + <CalendarD /> + <p className='text-[#616161] text-[14px] lg:text-[20px] font-medium'>تاریخ نوبت: <span className='text-[#2F2F2F] text-[14px] lg:text-[20px] font-bold'>{data.date_turn}</span></p> + </div> + </TextLoading> + <TextLoading loading={loading} width={100} height={20}> + <div className='flex items-start justify-start gap-[4px]'> + <ClockClinic /> + <p className='text-[#616161] text-[14px] lg:text-[20px] font-medium'>زمان نوبت: <span className='text-[#2F2F2F] text-[14px] lg:text-[20px] font-bold'>ساعت {data.time}</span></p> + </div> + </TextLoading> </li> <li className='flex flex-wrap items-center justify-start gap-y-[12px] gap-[32px]'> - <div className='flex items-start justify-start gap-[4px]'> - <LocationClinic /> - <p className='text-[#616161] text-[14px] lg:text-[16px] font-normal'>آدرس: <span className='text-[#2F2F2F] text-[14px] lg:text-[16px] font-normal'>{data.location}</span></p> - </div> - <Button - className='!py-[8px] !px-[12px] !gap-[8px]' - variant='text' - > - <RoutingC /> - <p className='text-[#5559CE] text-[14px] font-medium'>مسیریابی آدرس</p> - </Button> - </li> - <li className='flex items-center justify-start gap-[4px]'> - <CallD /> - <p className='text-[#616161] text-[14px] lg:text-[16px] font-normal'>تلفن: <span className='text-[#2F2F2F] text-[14px] lg:text-[16px] font-normal'>{data.phone}</span></p> + <TextLoading loading={loading} width={250} height={20}> + <div className='flex items-start justify-start gap-[4px]'> + <LocationClinic /> + <p className='text-[#616161] text-[14px] lg:text-[16px] font-normal'>آدرس: <span className='text-[#2F2F2F] text-[14px] lg:text-[16px] font-normal'>{data.location}</span></p> + </div> + </TextLoading> + <TextLoading loading={loading} width={120} height={30}> + <Button + className='!py-[8px] !px-[12px] !gap-[8px]' + variant='text' + > + <RoutingC /> + <p className='text-[#5559CE] text-[14px] font-medium'>مسیریابی آدرس</p> + </Button> + </TextLoading> </li> + <TextLoading loading={loading} width={120} height={18}> + <li className='flex items-center justify-start gap-[4px]'> + <CallD /> + <p className='text-[#616161] text-[14px] lg:text-[16px] font-normal'>تلفن: <span className='text-[#2F2F2F] text-[14px] lg:text-[16px] font-normal'>{data.phone}</span></p> + </li> + </TextLoading> </ul> <div className='py-[9px] lg:py-[18px] px-[12px] lg:pr-[16px] lg:pl-[40px] flex items-center gap-[4px] border border-solid border-[#EFEFEF] rounded-[4px] w-fit'> - <TicketD /> - <p className='text-[#616161] text-[14px] lg:text-[20px] font-medium'>مبلغ پرداخت شده : <span className='text-[#2F2F2F] text-[14px] lg:text-[20px] font-bold'>{data.amount_paid} تومان</span></p> + <TextLoading loading={loading} width={150} height={18}> + <TicketD /> + <p className='text-[#616161] text-[14px] lg:text-[20px] font-medium'>مبلغ پرداخت شده : <span className='text-[#2F2F2F] text-[14px] lg:text-[20px] font-bold'>{data.amount_paid} تومان</span></p> + </TextLoading> </div> </div> ) diff --git a/components/dashboard/userAccount/tabs/turns/isTurnsDetails/DetailSm.js b/components/dashboard/userAccount/tabs/turns/isTurnsDetails/DetailSm.js index 9cdb654..b50518e 100644 --- a/components/dashboard/userAccount/tabs/turns/isTurnsDetails/DetailSm.js +++ b/components/dashboard/userAccount/tabs/turns/isTurnsDetails/DetailSm.js @@ -4,57 +4,83 @@ import { Button } from '@mui/material'; import Image from 'next/image' import React from 'react' import ButtonData from './ButtonData'; +import CircularLoading from '@/app/component/loading/Circular'; +import TextLoading from '@/app/component/loading/Text'; -function DetailSm({ user }) { +function DetailSm({ user, loading }) { const data = user.turns[1]; return ( <div className='mt-[20px] block md:hidden'> <div className='flex items-center justify-start gap-[8px]'> - <Image - src={data.image} - alt='profile' - height={32} - width={32} - /> + <CircularLoading width={32} height={32} loading={loading}> + <Image + src={data.image} + alt='profile' + height={32} + width={32} + /> + </CircularLoading> <div className='flex flex-col justify-center items-start gap-[8px]'> - <p className='text-[#616161] text-[14px] font-medium'>{data.name}</p> - <p className='text-[#7E7E7E] text-[14px] font-normal'>{data.expertise}</p> + <TextLoading loading={loading} width={60} height={14}> + <p className='text-[#616161] text-[14px] font-medium'>{data.name}</p> + </TextLoading> + <TextLoading loading={loading} width={70} height={14}> + <p className='text-[#7E7E7E] text-[14px] font-normal'>{data.expertise}</p> + </TextLoading> </div> </div> <ul className='flex w-full flex-col items-start justify-start mt-[16px]'> <li className="flex items-center w-full justify-between"> - <p className="text-[#7E7E7E] text-[16px] font-normal">تاریخ نوبت:</p> - <p className="text-[#525252] text-[16px] font-medium">{data.date}</p> + <TextLoading loading={loading} width={70} height={16}> + <p className="text-[#7E7E7E] text-[16px] font-normal">تاریخ نوبت:</p> + </TextLoading> + <TextLoading loading={loading} width={55} height={16}> + <p className="text-[#525252] text-[16px] font-medium">{data.date}</p> + </TextLoading> </li> <span className='block w-full h-px bg-[#EFEFEF] mt-[12px] mb-[16px]'></span> <li className="flex flex-wrap items-center w-full justify-between"> - <p className="text-[#7E7E7E] text-[16px] font-normal">ساعت نوبت:</p> - <p className="text-[#525252] text-[16px] font-medium">{data.time}</p> + <TextLoading loading={loading} width={80} height={16}> + <p className="text-[#7E7E7E] text-[16px] font-normal">ساعت نوبت:</p> + </TextLoading> + <TextLoading loading={loading} width={60} height={16}> + <p className="text-[#525252] text-[16px] font-medium">{data.time}</p> + </TextLoading> </li> <span className='block w-full h-px bg-[#EFEFEF] mt-[12px] mb-[16px]'></span> - <li className="flex flex-wrap gap-y-[12px] items-center w-full justify-between"> - <p className="text-[#7E7E7E] text-[14px] font-normal">آدرس:<span className='text-[#616161]'>{data.location}</span></p> - <Button - className='!py-[8px] !border-[#EFEFEF] !px-[12px] !gap-[8px]' - variant='outlined' - > - <RoutingC /> - <p className='text-[#5559CE] text-[14px] font-medium'>مسیریابی آدرس</p> - </Button> + <li className="flex flex-wrap gap-x-[12px] gap-y-[12px] items-center w-full justify-between"> + <TextLoading loading={loading} width={200} height={16}> + <p className="text-[#7E7E7E] text-[14px] font-normal">آدرس:<span className='text-[#616161]'>{data.location}</span></p> + </TextLoading> + <TextLoading loading={loading} width={130} height={40}> + <Button + className='!py-[8px] !border-[#EFEFEF] !px-[12px] !gap-[8px]' + variant='outlined' + > + <RoutingC /> + <p className='text-[#5559CE] text-[14px] font-medium'>مسیریابی آدرس</p> + </Button> + </TextLoading> </li> - <p className='text-[#7E7E7E] text-[14px] font-normal mt-[12px]'>تلفن: <span className='text-[#616161]'>{data.phone}</span></p> + <TextLoading loading={loading} width={100} height={18}> + <p className='text-[#7E7E7E] text-[14px] font-normal mt-[12px]'>تلفن: <span className='text-[#616161]'>{data.phone}</span></p> + </TextLoading> <span className='block w-full h-px bg-[#EFEFEF] mt-[12px] mb-[16px]'></span> <li className='flex items-center justify-between w-full'> - <div className='flex items-center gap-[4px] w-fit'> - <TicketD /> - <p className='text-[#616161] text-[14px] lg:text-[20px] font-medium'>مبلغ پرداخت شده : <span className='text-[#2F2F2F] text-[14px] lg:text-[20px] font-bold'>{data.amount_paid} تومان</span></p> - </div> - <p className='text-[#616161] text-[14px] font-bold'>{data.amount_paid} تومان</p> + <TextLoading loading={loading} width={120} height={18}> + <div className='flex items-center gap-[4px] w-fit'> + <TicketD /> + <p className='text-[#616161] text-[14px] lg:text-[20px] font-medium'>مبلغ پرداخت شده : <span className='text-[#2F2F2F] text-[14px] lg:text-[20px] font-bold'>{data.amount_paid} تومان</span></p> + </div> + </TextLoading> + <TextLoading loading={loading} width={60} height={18}> + <p className='text-[#616161] text-[14px] font-bold'>{data.amount_paid} تومان</p> + </TextLoading> </li> </ul> - <ButtonData /> + <ButtonData loading={loading} /> </div> ) } diff --git a/components/dashboard/userAccount/tabs/turns/isTurnsDetails/Head.js b/components/dashboard/userAccount/tabs/turns/isTurnsDetails/Head.js index 386a642..aad3568 100644 --- a/components/dashboard/userAccount/tabs/turns/isTurnsDetails/Head.js +++ b/components/dashboard/userAccount/tabs/turns/isTurnsDetails/Head.js @@ -1,8 +1,9 @@ import ArrowRightS from "@/components/icons/ArrowRightS"; import { Button } from "@mui/material"; import ButtonData from "./ButtonData"; +import TextLoading from "@/app/component/loading/Text"; -function Head({ user, setIsTurnsDetails }) { +function Head({ user, setIsTurnsDetails, loading }) { return ( <div className="hidden md:flex flex-wrap gap-x-[24px] gap-y-[12px] items-center justify-between"> <div className="flex items-center justify-start gap-[12px] sm:gap-[16px] md:gap-[20px] lg:gap-[24px]"> @@ -12,9 +13,11 @@ function Head({ user, setIsTurnsDetails }) { > <ArrowRightS /> </Button> - <p className="text-[#3B3B3B] text-[14px] sm:text-[16px] md:text-[18px] lg:text-[20px] font-bold">جزئیات نوبت شما</p> + <TextLoading width={70} height={20} loading={loading}> + <p className="text-[#3B3B3B] text-[14px] sm:text-[16px] md:text-[18px] lg:text-[20px] font-bold">جزئیات نوبت شما</p> + </TextLoading> </div> - <ButtonData /> + <ButtonData loading={loading} /> </div> ) } diff --git a/components/dashboard/userAccount/tabs/turns/isTurnsDetails/index.js b/components/dashboard/userAccount/tabs/turns/isTurnsDetails/index.js index 157bb1a..ee5c315 100644 --- a/components/dashboard/userAccount/tabs/turns/isTurnsDetails/index.js +++ b/components/dashboard/userAccount/tabs/turns/isTurnsDetails/index.js @@ -3,15 +3,16 @@ import DetailLg from "./DetailLg" import DetailSm from "./DetailSm" import Head from "./Head" -function IsTurnsDetails({ user, setIsTurnsDetails }) { +function IsTurnsDetails({ user, setIsTurnsDetails, loading }) { return ( <div className="md:py-[20px] md:px-[24px] opacity-page"> <Head user={user} + loading={loading} setIsTurnsDetails={setIsTurnsDetails} /> - <DetailLg user={user} /> - <DetailSm user={user} /> + <DetailLg user={user} loading={loading} /> + <DetailSm user={user} loading={loading} /> </div> ) } diff --git a/components/dashboard/userAccount/tabs/turns/isTurnsDetails/modal/index.js b/components/dashboard/userAccount/tabs/turns/isTurnsDetails/modal/index.js index 5e4a581..c314cbe 100644 --- a/components/dashboard/userAccount/tabs/turns/isTurnsDetails/modal/index.js +++ b/components/dashboard/userAccount/tabs/turns/isTurnsDetails/modal/index.js @@ -3,7 +3,7 @@ import { Box, Button, Modal } from '@mui/material'; import { styleDefault } from '@/mui'; import CloseModalD from '@/components/icons/CloseModalD'; -function ModalDeleteComment() { +function ModalDeleteComment({ loading }) { const [open, setOpen] = useState(false); const handleOpen = () => setOpen(true); @@ -13,7 +13,11 @@ function ModalDeleteComment() { <div> {/* Button Modal */} <Button - className="!rounded-[4px] !border-[#828DE0] !py-[6px] md:!py-[7px] lg:!py-[8px] !px-[12px]" + className={` + ${!loading && '!border-[#828DE0]'} + !rounded-[4px] !py-[6px] md:!py-[7px] lg:!py-[8px] !px-[12px] + `} + disabled={loading} onClick={handleOpen} variant="outlined" > diff --git a/components/doctor/appointmentList/ItemAppointment.js b/components/doctor/appointmentList/ItemAppointment.js index d326acc..4448207 100644 --- a/components/doctor/appointmentList/ItemAppointment.js +++ b/components/doctor/appointmentList/ItemAppointment.js @@ -1,3 +1,5 @@ +import CircularLoading from '@/app/component/loading/Circular' +import TextLoading from '@/app/component/loading/Text' import ArrowLeftD from '@/components/icons/ArrowLeftD' import GreenCalendarTurn from '@/components/icons/GreenCalendarTurn' import { Button } from '@mui/material' @@ -5,7 +7,7 @@ import Image from 'next/image' import Link from 'next/link' import React from 'react' -function ItemAppointment({ turn, doctor }) { +function ItemAppointment({ turn, doctor, loading }) { return ( <li key={turn.id} @@ -14,26 +16,35 @@ function ItemAppointment({ turn, doctor }) { <p className='text-[#3B3B3B] text-[20px] font-bold'>نوبت دهی</p> <span className='block w-full h-px bg-[#EFEFEF] my-4'></span> <div className='flex items-center justify-start gap-3'> - <Image - src={doctor.img} - width={56} - height={56} - alt='doctor' - /> + <CircularLoading width={56} height={56} loading={loading}> + <Image + src={doctor.img} + width={56} + height={56} + alt='doctor' + /> + </CircularLoading> <div className='flex flex-col items-start justify-center gap-2'> - <p className='text-[#3B3B3B] text-[14px] font-bold'>{doctor.name}</p> - <p className="text-[#525252] text-[14px] font-medium">تخصص: {doctor.expertise}</p> + <TextLoading width={60} height={15} loading={loading}> + <p className='text-[#3B3B3B] text-[14px] font-bold'>{doctor.name}</p> + </TextLoading> + <TextLoading width={65} height={15} loading={loading}> + <p className="text-[#525252] text-[14px] font-medium">تخصص: {doctor.expertise}</p> + </TextLoading> </div> </div> <div className='flex mt-5 gap-2 items-center justify-between'> <div className='flex items-start justify-start gap-1'> <GreenCalendarTurn /> - <p className='text-[#05BA58] text-[12px] font-medium'>اولین نوبت آزاد: {turn.first_free_turn}</p> + <TextLoading width={100} height={15} loading={loading}> + <p className='text-[#05BA58] text-[12px] font-medium'>اولین نوبت آزاد: {turn.first_free_turn}</p> + </TextLoading> </div> - <Link href={`/booking/${turn.id}`}> + <Link href={loading ? '#' : `/booking/${turn.id}`}> <Button variant='contained' className='!py-2 !px-3 xl:!px-6 gap-1' + disabled={loading} > دریافت نوبت <div className='w-[20px] h-[20px]'> diff --git a/components/doctor/appointmentList/index.js b/components/doctor/appointmentList/index.js index 608e951..b172c02 100644 --- a/components/doctor/appointmentList/index.js +++ b/components/doctor/appointmentList/index.js @@ -6,7 +6,7 @@ import ItemAppointment from './ItemAppointment'; import ArrowLeftD from '@/components/icons/ArrowLeftD'; import Link from 'next/link'; -function AppointmentList({ doctor }) { +function AppointmentList({ doctor, loading }) { const itemActive = turns[0]; @@ -18,6 +18,7 @@ function AppointmentList({ doctor }) { turn={item} key={item.id} doctor={doctor} + loading={loading} /> ))} </ul> diff --git a/components/doctor/detailDoctor/Title.js b/components/doctor/detailDoctor/Title.js index e77b392..cea0ff9 100644 --- a/components/doctor/detailDoctor/Title.js +++ b/components/doctor/detailDoctor/Title.js @@ -1,43 +1,58 @@ +import CircularLoading from "@/app/component/loading/Circular" +import CustomLoading from "@/app/component/loading/Custom" +import TextLoading from "@/app/component/loading/Text" import LikeDI from "@/components/icons/LikeDI" import StarDI from "@/components/icons/StarDI" import TickCircle from "@/components/icons/TickCircle" import Image from "next/image" -function Title({ doctor }) { +function Title({ doctor, loading }) { return ( <div className="flex flex-col lg:flex-row items-center justify-start gap-[8px] lg:gap-[32px]"> - <Image - className=" + <CircularLoading loading={loading} width={100} height={100}> + <Image + className=" w-[40px] sm:w-[81px] md:w-[123px] lg:w-[164px] h-[40px] sm:h-[81px] md:h-[123px] lg:h-[164px] " - src={doctor.img} - alt="img-doctor" - height={164} - width={164} - /> + src={doctor.img} + alt="img-doctor" + height={164} + width={164} + /> + </CircularLoading> <div className="flex flex-col items-center lg:items-start gap-[8px] lg:gap-[16px]"> - <p className="text-[#3B3B3B] text-[14px] sm:text-[16px] md:text-[18px] lg:text-[20px] font-bold">{doctor.name}</p> - <p className="text-[#525252] text-[14px] md:text-[16px] font-medium">تخصص: {doctor.expertise}</p> + <TextLoading loading={loading} width={90} height={20}> + <p className="text-[#3B3B3B] text-[14px] sm:text-[16px] md:text-[18px] lg:text-[20px] font-bold">{doctor.name}</p> + </TextLoading> + <TextLoading loading={loading} width={100} height={20}> + <p className="text-[#525252] text-[14px] md:text-[16px] font-medium">تخصص: {doctor.expertise}</p> + </TextLoading> <div className="flex items-center justify-start gap-11"> - <p className="text-[#525252] text-[16px] font-medium">{doctor.experience} سال تجربه</p> + <TextLoading loading={loading} width={60} height={20}> + <p className="text-[#525252] text-[16px] font-medium">{doctor.experience} سال تجربه</p> + </TextLoading> <div className="flex items-center gap-1"> <div className="hidden lg:flex"> <TickCircle /> </div> - <p className="text-[#525252] text-[12px] md:text-[14px] lg:text-[16px] font-medium">کد نظام پزشکی: {doctor.medical_system_code}</p> + <TextLoading loading={loading} width={120} height={20}> + <p className="text-[#525252] text-[12px] md:text-[14px] lg:text-[16px] font-medium">کد نظام پزشکی: {doctor.medical_system_code}</p> + </TextLoading> </div> </div> - <div className="flex items-center justify-start gap-2"> - <div className="flex p-1 gap-0.5 items-start justify-center"> - <StarDI /> - <p className="text-[#616161] text-[12px] md:text-[14px] font-normal">امتیاز: {doctor.point}</p> + <CustomLoading loading={loading} width={160} height={25}> + <div className="flex items-center justify-start gap-2"> + <div className="flex p-1 gap-0.5 items-start justify-center"> + <StarDI /> + <p className="text-[#616161] text-[12px] md:text-[14px] font-normal">امتیاز: {doctor.point}</p> + </div> + <div className="flex p-1 items-start gap-0.5"> + <LikeDI /> + <p className="text-[#616161] text-[12px] md:text-[14px] font-normal">{doctor.satisfaction}% رضایت کاربران</p> + </div> </div> - <div className="flex p-1 items-start gap-0.5"> - <LikeDI /> - <p className="text-[#616161] text-[12px] md:text-[14px] font-normal">{doctor.satisfaction}% رضایت کاربران</p> - </div> - </div> + </CustomLoading> </div> </div> ) diff --git a/components/doctor/detailDoctor/cards/AboutDcotor.js b/components/doctor/detailDoctor/cards/AboutDcotor.js index 08dcf79..b7f9433 100644 --- a/components/doctor/detailDoctor/cards/AboutDcotor.js +++ b/components/doctor/detailDoctor/cards/AboutDcotor.js @@ -2,8 +2,10 @@ import { useState } from "react"; import { Button } from "@mui/material" +import MultilineLoading from "@/app/component/loading/Multiline"; +import TextLoading from "@/app/component/loading/Text"; -function AboutDcotor({ doctor }) { +function AboutDcotor({ doctor, loading }) { const [isMore, setIsMore] = useState(false); @@ -14,24 +16,26 @@ function AboutDcotor({ doctor }) { className='absolute -translate-y-[148px] sm:-translate-y-[157px] md:-translate-y-[166px] lg:-translate-y-[176px]' ></a> <div className="flex flex-col items-center justify-center"> - <p - className={` + <MultilineLoading loading={loading} width='full' height={18} line={30}> + <p + className={` text-[#616161] text-[14px] font-normal text-justify 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]' - } + 'after:bg-transparent max-h-screen' : + 'after:bg-[linear-gradient(transparent,#FAFAFA)] max-h-[200px]' + } `} - >{doctor.detail}</p> - <Button - className="!text-[#F17732] md:!hidden !text-[14px] !font-light !p-2" - onClick={() => setIsMore(!isMore)} - variant="text" - > - {isMore ? 'مطالعه کمتر' : 'مطالعه بیشتر'} - </Button> + >{doctor.detail}</p> + <Button + className="!text-[#F17732] md:!hidden !text-[14px] !font-light !p-2" + onClick={() => setIsMore(!isMore)} + variant="text" + > + {isMore ? 'مطالعه کمتر' : 'مطالعه بیشتر'} + </Button> + </MultilineLoading> </div> <div className="mt-[12px] lg:mt-[8px] mb-6 md:mb-7 lg:mb-8"> <p className="text-[#525252] text-[14px] md:text-[16px] font-bold">تخصص ها</p> @@ -39,7 +43,9 @@ function AboutDcotor({ doctor }) { {doctor.specialties.map((item, idx) => ( <li key={idx} className="flex items-center justify-start gap-1"> <span className="w-2 h-2 bg-[#F17732] rounded-full"></span> - <p className="text-[#616161] text-[16px] font-normal text-nowrap">{item}</p> + <TextLoading loading={loading} width={70} height={18}> + <p className="text-[#616161] text-[16px] font-normal text-nowrap">{item}</p> + </TextLoading> </li> ))} </ul> diff --git a/components/doctor/detailDoctor/cards/comments/chart/ProgressAll.js b/components/doctor/detailDoctor/cards/comments/chart/ProgressAll.js index 59e153f..a5ddf97 100644 --- a/components/doctor/detailDoctor/cards/comments/chart/ProgressAll.js +++ b/components/doctor/detailDoctor/cards/comments/chart/ProgressAll.js @@ -1,30 +1,33 @@ +import CircularLoading from "@/app/component/loading/Circular" import { numberToArStyle } from "@/helper" import { CircularProgress } from "@mui/material" -function ProgressAll({ doctor }) { +function ProgressAll({ doctor, loading }) { return ( <div className="hidden lg:flex w-full h-fit relative min-w-[145px] max-w-[150px]"> - <CircularProgress - variant="determinate" - value={doctor.total_user_satisfaction} - sx={{ - '& .MuiCircularProgress-circle': { - stroke: '#05BA58', - strokeLinecap: 'round' - }, - '& .MuiCircularProgress-svg': { - borderRadius: '50%', - boxShadow: 'inset 0 0 0 11px #D7D7D7' - } - }} - className="!w-full !h-full" - /> - <div - className="flex flex-col justify-center items-center absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 gap-1" - > - <p className="text-[#525252] text-[12px] font-normal text-center">مجموع<br />رضایت کاربران</p> - <p>{numberToArStyle(doctor.total_user_satisfaction)}%</p> - </div> + <CircularLoading loading={loading} width={120} height={120}> + <CircularProgress + variant="determinate" + value={doctor.total_user_satisfaction} + sx={{ + '& .MuiCircularProgress-circle': { + stroke: '#05BA58', + strokeLinecap: 'round' + }, + '& .MuiCircularProgress-svg': { + borderRadius: '50%', + boxShadow: 'inset 0 0 0 11px #D7D7D7' + } + }} + className="!w-full !h-full" + /> + <div + className="flex flex-col justify-center items-center absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 gap-1" + > + <p className="text-[#525252] text-[12px] font-normal text-center">مجموع<br />رضایت کاربران</p> + <p>{numberToArStyle(doctor.total_user_satisfaction)}%</p> + </div> + </CircularLoading> </div> ) } diff --git a/components/doctor/detailDoctor/cards/comments/chart/index.js b/components/doctor/detailDoctor/cards/comments/chart/index.js index 3bc2de0..70f53e0 100644 --- a/components/doctor/detailDoctor/cards/comments/chart/index.js +++ b/components/doctor/detailDoctor/cards/comments/chart/index.js @@ -3,44 +3,57 @@ import ProgressAll from "./ProgressAll" import StarDI from "@/components/icons/StarDI" import LikeDI from "@/components/icons/LikeDI" import ProgressDetail from "@/app/component/ProfressDetail" +import TextLoading from "@/app/component/loading/Text" +import CustomLoading from "@/app/component/loading/Custom" +import CircularLoading from "@/app/component/loading/Circular" -function Chart({ doctor }) { +function Chart({ doctor, loading }) { return ( <div className=' rounded-lg my-[12px] sm:my-[16px] md:my-[20px] lg:my-[24px] border border-[#EFEFEF] bg-[#FFF] pt-[12px] md:pt-[14px] lg:pt-[16px] pb-[12px] sm:pb-[16px] md:pb-[20px] lg:pb-[24px] px-[12px] sm:px-[16px] md:px-[20px] lg:px-[24px] '> - <div className='flex items-center justify-start gap-2.5'> - <p className="text-[#616161] text-[14px] font-medium">امتیاز کلی کاربران: {doctor.overall_score} از 5</p> - <p className="text-[#7E7E7E] text-[14px] font-normal">(از مجموع {doctor.comments.length} نظر)</p> + <TextLoading loading={loading} width={130} height={20}> + <div className='flex items-center justify-start gap-2.5'> + <p className="text-[#616161] text-[14px] font-medium">امتیاز کلی کاربران: {doctor.overall_score} از 5</p> + <p className="text-[#7E7E7E] text-[14px] font-normal">(از مجموع {doctor.comments.length} نظر)</p> + </div> + </TextLoading> + <div className={`${loading ? 'mt-4 mb-6' : 'mt-0 mb-0'} hidden md:flex`}> + <TextLoading loading={loading} width={160} height={20}> + <Rating + readOnly + value={4} + size="small" + name="read-only" + className="!mt-4 !mb-6 !hidden lg:!flex" + /> + </TextLoading> </div> - <Rating - readOnly - value={4} - size="small" - name="read-only" - className="!mt-4 !mb-6 !hidden lg:!flex" - /> - <div className="flex items-center justify-start gap-2 my-[12px]"> - <div className="flex p-1 gap-0.5 items-start justify-center"> - <StarDI /> - <p className="text-[#616161] text-[12px] md:text-[14px] font-normal">امتیاز: {doctor.point}</p> - </div> - <div className="flex p-1 items-start gap-0.5"> - <LikeDI /> - <p className="text-[#616161] text-[12px] md:text-[14px] font-normal">{doctor.satisfaction}% رضایت کاربران</p> - </div> + <div className="flex items-center justify-start gap-2 my-[12px] md:hidden"> + <CustomLoading loading={loading} width={130} height={30}> + <div className="flex p-1 gap-0.5 items-start justify-center"> + <StarDI /> + <p className="text-[#616161] text-[12px] md:text-[14px] font-normal">امتیاز: {doctor.point}</p> + </div> + <div className="flex p-1 items-start gap-0.5"> + <LikeDI /> + <p className="text-[#616161] text-[12px] md:text-[14px] font-normal">{doctor.satisfaction}% رضایت کاربران</p> + </div> + </CustomLoading> </div> <div className="flex flex-wrap items-center justify-center gap-[50px]"> - <ul className="flex w-full lg:w-fit flex-col items-start justify-start gap-1.5"> + <ul 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) => ( - <ProgressDetail - data={item} - key={idx} - /> + <TextLoading width='full' height={20} loading={loading}> + <ProgressDetail + data={item} + key={idx} + /> + </TextLoading> ))} </ul> - <ProgressAll doctor={doctor} /> + <ProgressAll doctor={doctor} loading={loading} /> </div> </div> ) diff --git a/components/doctor/detailDoctor/cards/comments/index.js b/components/doctor/detailDoctor/cards/comments/index.js index 0de094f..e52d8d9 100644 --- a/components/doctor/detailDoctor/cards/comments/index.js +++ b/components/doctor/detailDoctor/cards/comments/index.js @@ -1,9 +1,8 @@ -import { Button } from '@mui/material' import Chart from './chart' import Comment from '@/app/component/comment' import ModalAnswer from './modal/ModalAnswer' -function Comments({ doctor }) { +function Comments({ doctor, loading }) { return ( <div className='mt-[24px] sm:mt-[27px] md:mt-[29px] lg:mt-[32px]'> <a @@ -15,8 +14,8 @@ function Comments({ doctor }) { <p className='text-[#616161] text-[16px] font-normal'>شما هم نظر خود را در مورد این پزشک به اشتراک بگذارید:</p> <ModalAnswer doctor={doctor} /> </div> - <Chart doctor={doctor} /> - <Comment data={doctor} /> + <Chart doctor={doctor} loading={loading} /> + <Comment data={doctor} loading={loading} /> </div> ) } diff --git a/components/doctor/detailDoctor/cards/locations/index.js b/components/doctor/detailDoctor/cards/locations/index.js index 421d470..d2d970a 100644 --- a/components/doctor/detailDoctor/cards/locations/index.js +++ b/components/doctor/detailDoctor/cards/locations/index.js @@ -1,6 +1,7 @@ +import CustomLoading from "@/app/component/loading/Custom" import Item from "./Item" -function Locations({ doctor }) { +function Locations({ doctor, loading }) { return ( <div> <p @@ -8,15 +9,17 @@ function Locations({ doctor }) { >موقعیت مکانی </p> <ul className="flex w-full mt-[24px] flex-col justify-center items-start"> {doctor.locations.map((item, idx) => ( - <li className="w-full"> - <Item - key={idx} - data={item} - /> - {doctor.locations.length > idx + 1 && ( - <span className="w-full h-px bg-[#EFEFEF] block my-[12px] md:my-[14px] lg:my-[16px]"></span> - )} - </li> + <CustomLoading loading={loading} width='full' height={40}> + <li className="w-full"> + <Item + key={idx} + data={item} + /> + {doctor.locations.length > idx + 1 && ( + <span className="w-full h-px bg-[#EFEFEF] block my-[12px] md:my-[14px] lg:my-[16px]"></span> + )} + </li> + </CustomLoading> ))} </ul> </div> diff --git a/components/doctor/detailDoctor/index.js b/components/doctor/detailDoctor/index.js index 4a37d7c..4ae9533 100644 --- a/components/doctor/detailDoctor/index.js +++ b/components/doctor/detailDoctor/index.js @@ -5,17 +5,17 @@ import AboutDcotor from "./cards/AboutDcotor" import Comments from "./cards/comments" import Locations from "./cards/locations" -function DetailDoctor({ doctor }) { +function DetailDoctor({ doctor, loading }) { return ( <div className="w-full lg:w-[59%]"> <div className="hidden lg:flex"> <Share /> </div> - <Title doctor={doctor} /> + <Title doctor={doctor} loading={loading} /> <Link /> - <AboutDcotor doctor={doctor} /> - <Locations doctor={doctor} /> - <Comments doctor={doctor} /> + <AboutDcotor loading={loading} doctor={doctor} /> + <Locations loading={loading} doctor={doctor} /> + <Comments loading={loading} doctor={doctor} /> </div> ) } diff --git a/components/doctor/index.js b/components/doctor/index.js index b9801b1..414baf6 100644 --- a/components/doctor/index.js +++ b/components/doctor/index.js @@ -1,22 +1,37 @@ +'use client'; + +import { useEffect, useState } from "react"; import AppointmentList from "./appointmentList" import DetailDoctor from "./detailDoctor" import Share from "./detailDoctor/Share"; +import CustomLoading from "@/app/component/loading/Custom"; function DoctorPage({ doctor }) { + + const [loading, setLoading] = useState(true); + + useEffect(() => { + setTimeout(() => { + setLoading(false); + }, 2000); + }, []); + return ( <div className="pt-[92px] sm:pt-[120px] mt:pt-[148px] lg:pt-[176px] mt-[px] padding-responsive"> <div className="flex items-center justify-between"> - <div className="flex items-center justify-start text-[14px] md:text-[16px] font-normal"> - <p className="text-[#9B9B9B] text-nowrap">متخصص {doctor.expertise} {' >'}</p> - <p className="text-[#525252] text-nowrap mr-1">{doctor.name}</p> - </div> + <CustomLoading loading={loading} width={180} height={25}> + <div className="flex items-center justify-start text-[14px] md:text-[16px] font-normal"> + <p className="text-[#9B9B9B] text-nowrap">متخصص {doctor.expertise} {' >'}</p> + <p className="text-[#525252] text-nowrap mr-1">{doctor.name}</p> + </div> + </CustomLoading> <div className="flex lg:hidden"> <Share /> </div> </div> <div className="flex items-start justify-center gap-6 mt-[30px]"> - <DetailDoctor doctor={doctor} /> - <AppointmentList doctor={doctor} /> + <DetailDoctor doctor={doctor} loading={loading} /> + <AppointmentList doctor={doctor} loading={loading} /> </div> </div> ) diff --git a/components/doctors/index.js b/components/doctors/index.js index 015b51a..682b3b9 100644 --- a/components/doctors/index.js +++ b/components/doctors/index.js @@ -1,14 +1,14 @@ 'use client'; -import { useState } from "react"; +import { useEffect, useState } from "react"; import SearchBar from "./search"; import SortList from "./sortlist"; import ListDoctors from "./listDoctors"; - import LocationD from "../icons/LocationD"; function DoctorsPage() { + const [loading, setLoading] = useState(true); const [data, setData] = useState({ expertise: '', gender: 0, @@ -16,6 +16,12 @@ function DoctorsPage() { turn: true }); + useEffect(() => { + setTimeout(() => { + setLoading(false); + }, 2000); + }, []); + return ( <div className="pt-[95px] sm:pt-[120px] padding-responsive"> <div className="flex justify-center gap-[16px] sm:gap-[19px] md:gap-[22px] lg:gap-[24px] flex-col items-center mt-0 md:mt-[40px] lg:mt-[90px]"> @@ -28,7 +34,7 @@ function DoctorsPage() { <SortList data={data} setData={setData} /> </div> </div> - <ListDoctors /> + <ListDoctors loading={loading} /> </div> ) } diff --git a/components/doctors/listDoctors/index.js b/components/doctors/listDoctors/index.js index 2c067a6..e281d39 100644 --- a/components/doctors/listDoctors/index.js +++ b/components/doctors/listDoctors/index.js @@ -2,16 +2,17 @@ import doctors from '@/data/doctors.json' import Pagination from '@/app/component/Pagination'; import ItemDoctor from '@/app/component/ItemDoctor'; -function ListDoctors() { +function ListDoctors({ loading }) { return ( <> <ul className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 mt-[24px] sm:mt-[37px] md:mt-[50px] lg:mt-[64px] gap-[24px]"> - {doctors.map(doctor => ( + {doctors.map(doctor => <ItemDoctor key={doctor.id} doctor={doctor} + loading={loading} /> - ))} + )} </ul> <div className='mt-[56px] flex justify-center'> <Pagination /> diff --git a/components/specialties/index.js b/components/specialties/index.js index b1b36f7..271d423 100644 --- a/components/specialties/index.js +++ b/components/specialties/index.js @@ -1,8 +1,20 @@ -import HeadPageList from "@/app/component/head" -import SmSearch from "../searchHead/SmSearch" -import List from "./list" +'use client'; + +import { useEffect, useState } from "react"; +import List from "./list"; +import SmSearch from "../searchHead/SmSearch"; +import HeadPageList from "@/app/component/head"; function SpecialtiesPage() { + + const [loading, setLoading] = useState(true); + + useEffect(() => { + setTimeout(() => { + setLoading(false); + }, 2000); + }, []); + return ( <div className=""> <HeadPageList @@ -11,7 +23,7 @@ function SpecialtiesPage() { > <SmSearch placeholder='جستجوی تخصص' /> </HeadPageList> - <List /> + <List loading={loading} /> </div> ) } diff --git a/components/specialties/list/ItemSpecialties.js b/components/specialties/list/ItemSpecialties.js index 9488025..4e19956 100644 --- a/components/specialties/list/ItemSpecialties.js +++ b/components/specialties/list/ItemSpecialties.js @@ -1,14 +1,19 @@ +import TextLoading from '@/app/component/loading/Text' import React from 'react' -function ItemSpecialties({ data }) { +function ItemSpecialties({ data, loading }) { return ( <li className='py-[17.5px] px-[12px] flex flex-col justify-center items-center gap-[16px] rounded-lg bg-[#FFF] shadow-[0px_1px_24.8px_0px_rgba(204,_204,_204,_0.18)] hover:bg-[#5559CE] transition-all duration-500 cursor-pointer hover-mode-item-speciality' > - <p className='text-[#3B3B3B] text-[16px] font-bold'>{data.name}</p> - <p className='text-[#7E7E7E] text-[14px] font-medium'>{data.number_of_doctors} پزشک</p> + <TextLoading loading={loading} width={70} height={18}> + <p className='text-[#3B3B3B] text-[16px] font-bold'>{data.name}</p> + </TextLoading> + <TextLoading loading={loading} width={50} height={18}> + <p className='text-[#7E7E7E] text-[14px] font-medium'>{data.number_of_doctors} پزشک</p> + </TextLoading> </li> ) } diff --git a/components/specialties/list/index.js b/components/specialties/list/index.js index eaf4712..8528ebc 100644 --- a/components/specialties/list/index.js +++ b/components/specialties/list/index.js @@ -3,7 +3,7 @@ import ItemSpecialties from './ItemSpecialties'; import MenuS from '@/components/icons/MenuS'; import Pagination from '@/app/component/Pagination'; -function List() { +function List({ loading }) { return ( <div className='bg-[#FAFAFA]'> <div className='flex items-center justify-center gap-[12px] pt-[24px] mb-[40px]'> @@ -15,6 +15,7 @@ function List() { gap-y-[16px] sm:gap-y-[24px] md:gap-y-[32px] lg:gap-y-[40px]"> {specialties.map(speciality => ( <ItemSpecialties + loading={loading} data={speciality} key={speciality.id} />