diff --git a/client/src/components/HeroSection.js b/client/src/components/HeroSection.js index 57fe100..10305f8 100644 --- a/client/src/components/HeroSection.js +++ b/client/src/components/HeroSection.js @@ -1,13 +1,43 @@ -import React from 'react'; +import React, { useState, useEffect } from 'react'; import styles from './HeroSection.module.css'; import pic1 from '../assets/pic5.webp'; +import Skeleton from './ui/Skeleton'; const HeroSection = () => { + const [imageLoaded, setImageLoaded] = useState(false); + const [imageError, setImageError] = useState(false); + + useEffect(() => { + const img = new Image(); + img.src = pic1; + img.onload = () => setImageLoaded(true); + img.onerror = () => setImageError(true); + }, []); + return (
- Doctor with patient + {!imageLoaded && !imageError && ( + + )} + {(imageLoaded || imageError) && ( + Doctor with patient setImageLoaded(true)} + onError={() => setImageError(true)} + style={{ opacity: imageLoaded ? 1 : 0 }} + /> + )}

diff --git a/client/src/components/HeroSection.module.css b/client/src/components/HeroSection.module.css index 7674b19..6f427ac 100644 --- a/client/src/components/HeroSection.module.css +++ b/client/src/components/HeroSection.module.css @@ -4,6 +4,36 @@ display: flex; flex-direction: column; gap: 40px; + position: relative; + overflow: hidden; +} + +/* Skeleton loader styles */ +.skeletonImage { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + border-radius: 12px; + overflow: hidden; + background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%); + background-size: 200% 100%; + animation: shimmer 1.5s infinite; +} + +@keyframes shimmer { + 0% { + background-position: -200% 0; + } + 100% { + background-position: 200% 0; + } +} + +/* Dark mode support */ +.dark .skeletonImage { + background: linear-gradient(90deg, #2d3748 25%, #4a5568 50%, #2d3748 75%); } .heroContainer, @@ -26,8 +56,29 @@ box-shadow: 0 12px 24px rgba(0, 0, 0, 0.15); } +.heroImage { + position: relative; + width: 100%; + max-width: 450px; + height: 300px; + border-radius: 12px; + overflow: hidden; + background: #f0f0f0; +} + +.heroImage img { + width: 100%; + height: 100%; + object-fit: cover; + border-radius: 12px; + opacity: 0; + transition: opacity 0.3s ease-in-out; +} + +.heroImage img.loaded { + opacity: 1; +} -.heroImage img, .messageImage img { width: 100%; max-width: 450px; @@ -36,7 +87,6 @@ border-radius: 12px; } - .heroText, .messageText { flex: 1; @@ -53,12 +103,12 @@ font-weight: 500; margin: 0; } + .highlight { color: #0f4613; font-weight: bold; } - @media (max-width: 1024px) { .heroContainer, .messageContainer { @@ -67,8 +117,25 @@ padding: 20px; } + .heroImage { + max-width: 100%; + height: 250px; + margin: 0 auto; + } + .heroImage img, .messageImage img { max-width: 100%; } +} + +/* Animation for image load */ +@keyframes fadeIn { + from { opacity: 0; } + to { opacity: 1; } +} + +/* Dark mode styles */ +.dark .heroImage { + background: #2d3748; } \ No newline at end of file diff --git a/client/src/components/ui/Skeleton.js b/client/src/components/ui/Skeleton.js new file mode 100644 index 0000000..5c5525c --- /dev/null +++ b/client/src/components/ui/Skeleton.js @@ -0,0 +1,14 @@ +import React from 'react'; +import styles from './Skeleton.module.css'; + +const Skeleton = ({ width, height, className = '', style = {} }) => { + return ( +