pwf-website-new/client/src/components/photo-gallery.tsx

127 lines
5.3 KiB
TypeScript

import { useQuery } from "@tanstack/react-query";
import { useState } from "react";
interface InstagramPost {
id: string;
media_type: 'IMAGE' | 'VIDEO' | 'CAROUSEL_ALBUM';
media_url: string;
permalink: string;
caption?: string;
timestamp: string;
}
export function PhotoGallery() {
const [showAllPosts, setShowAllPosts] = useState(false);
const { data: posts, isLoading, error } = useQuery<InstagramPost[]>({
queryKey: ['/api/instagram-feed'],
staleTime: 1000 * 60 * 30, // Cache for 30 minutes
});
const displayPosts = showAllPosts ? posts : posts?.slice(0, 6);
return (
<section className="py-12 bg-white">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="text-center mb-8">
<h2 className="text-3xl md:text-4xl font-playfair font-semibold text-rose mb-4">
Follow My Journey
</h2>
</div>
<div className="flex justify-center">
<div className="w-full max-w-4xl">
{isLoading && (
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
{[1, 2, 3, 4, 5, 6].map((index) => (
<div key={index} className="aspect-square bg-gray-200 rounded-lg animate-pulse"></div>
))}
</div>
)}
{error && (
<div className="bg-gray-50 rounded-lg p-8 text-center">
<div className="mb-6">
<i className="fab fa-instagram text-6xl text-pink-500 mb-4"></i>
<p className="text-gray-600 mb-6">Follow me on Instagram for daily inspiration, movement tips, and behind-the-scenes content from my classes.</p>
<a
href="https://www.instagram.com/fadia.elgharib/"
target="_blank"
rel="noopener noreferrer"
className="inline-flex items-center px-6 py-3 bg-rose text-white font-semibold rounded-full hover:bg-opacity-90 transition duration-300"
>
<i className="fab fa-instagram mr-2"></i>
Visit Instagram
</a>
</div>
</div>
)}
{posts && posts.length > 0 && (
<div className="space-y-6">
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
{displayPosts?.map((post: InstagramPost) => (
<a
key={post.id}
href={post.permalink}
target="_blank"
rel="noopener noreferrer"
className="group block aspect-square bg-gray-100 rounded-lg overflow-hidden hover:shadow-lg transition-shadow duration-300"
>
{post.media_type === 'VIDEO' ? (
<div className="relative w-full h-full">
<video
src={post.media_url}
className="w-full h-full object-cover group-hover:scale-105 transition-transform duration-300"
muted
loop
playsInline
onMouseEnter={(e) => e.currentTarget.play()}
onMouseLeave={(e) => e.currentTarget.pause()}
/>
<div className="absolute inset-0 bg-black bg-opacity-0 group-hover:bg-opacity-10 transition-all duration-300 flex items-center justify-center">
<i className="fas fa-play text-white text-2xl opacity-0 group-hover:opacity-80 transition-opacity duration-300"></i>
</div>
</div>
) : (
<img
src={post.media_url}
alt={post.caption ? post.caption.substring(0, 100) + '...' : 'Instagram post'}
className="w-full h-full object-cover group-hover:scale-105 transition-transform duration-300"
loading="lazy"
/>
)}
</a>
))}
</div>
{posts.length > 6 && (
<div className="text-center">
<button
onClick={() => setShowAllPosts(!showAllPosts)}
className="px-6 py-3 bg-rose text-white font-semibold rounded-full hover:bg-opacity-90 transition duration-300"
>
{showAllPosts ? 'Show Less' : `View All ${posts.length} Posts`}
</button>
</div>
)}
<div className="text-center mt-8">
<a
href="https://www.instagram.com/fadia.elgharib/"
target="_blank"
rel="noopener noreferrer"
className="inline-flex items-center px-6 py-3 bg-rose text-white font-semibold rounded-full hover:bg-opacity-90 transition duration-300"
>
<i className="fab fa-instagram mr-2"></i>
Follow on Instagram
</a>
</div>
</div>
)}
</div>
</div>
</div>
</section>
);
}