Files
CityCards-Website/src/components/MelbourneBlogs.tsx
2026-04-24 13:52:27 +05:30

307 lines
15 KiB
TypeScript

import { motion } from 'motion/react';
import { ImageWithFallback } from './figma/ImageWithFallback';
import { Calendar, Clock, User, ArrowRight, Coffee, Camera, MapPin, Star } from 'lucide-react';
import { Button } from './ui/button';
import { useRef } from "react";
import { useNavigate } from 'react-router-dom';
const blogPosts = [
{
id: 1,
title: "Hidden Laneways: Melbourne's Street Art Revolution",
excerpt: "Discover the vibrant street art scene that has transformed Melbourne's narrow alleyways into outdoor galleries, making the city a global street art capital.",
image: "https://images.unsplash.com/photo-1705120624704-0970afc29fea?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w3Nzg4Nzd8MHwxfHNlYXJjaHwxfHxtZWxib3VybmUlMjBzdHJlZXQlMjBhcnQlMjBsYW5ld2F5c3xlbnwxfHx8fDE3NTczMzkyNjZ8MA&ixlib=rb-4.1.0&q=80&w=1080&utm_source=figma&utm_medium=referral",
author: "Melbourne Explorer",
date: "Dec 15, 2024",
readTime: "5 min read",
category: "Culture",
featured: true,
tags: ["Street Art", "Laneways", "Culture", "Photography"]
},
{
id: 2,
title: "Coffee Capital: Melbourne's World-Famous Cafe Culture",
excerpt: "From hole-in-the-wall espresso bars to artisanal third-wave coffee shops, explore why Melbourne is considered the world's coffee capital.",
image: "https://images.unsplash.com/photo-1681745623555-efc392301d6d?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w3Nzg4Nzd8MHwxfHNlYXJjaHwxfHxtZWxib3VybmUlMjBjb2ZmZWUlMjBjdWx0dXJlJTIwY2FmZXxlbnwxfHx8fDE3NTczMzkyNzJ8MA&ixlib=rb-4.1.0&q=80&w=1080&utm_source=figma&utm_medium=referral",
author: "Coffee Connoisseur",
date: "Dec 12, 2024",
readTime: "7 min read",
category: "Food & Drink",
featured: false,
tags: ["Coffee", "Food", "Local Culture", "Cafes"]
},
{
id: 3,
title: "Royal Botanic Gardens: Melbourne's Green Oasis",
excerpt: "Escape the urban hustle in Melbourne's 38-hectare botanical paradise, home to over 8,500 plant species and stunning city views.",
image: "https://images.unsplash.com/photo-1721272962395-a848331ce92d?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w3Nzg4Nzd8MHwxfHNlYXJjaHwxfHxtZWxib3VybmUlMjByb3lhbCUyMGJvdGFuaWMlMjBnYXJkZW5zfGVufDF8fHx8MTc1NzMzNzc4OXww&ixlib=rb-4.1.0&q=80&w=1080&utm_source=figma&utm_medium=referral",
author: "Nature Guide",
date: "Dec 10, 2024",
readTime: "4 min read",
category: "Nature",
featured: false,
tags: ["Gardens", "Nature", "Photography", "Relaxation"]
},
{
id: 4,
title: "Sports Capital: Melbourne's Sporting Heritage",
excerpt: "From the iconic MCG to Formula 1 racing, discover why Melbourne holds the title of Australia's sporting capital and home to major international events.",
image: "https://images.unsplash.com/photo-1720347247737-9252d85d3027?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w3Nzg4Nzd8MHwxfHNlYXJjaHwxfHxtZWxib3VybmUlMjBjaXR5JTIwc2t5bGluZSUyMGZsaW5kZXJzJTIwc3RyZWV0fGVufDF8fHx8MTc1NzMzOTAyNHww&ixlib=rb-4.1.0&q=80&w=1080&utm_source=figma&utm_medium=referral",
author: "Sports Fan",
date: "Dec 8, 2024",
readTime: "6 min read",
category: "Sports",
featured: false,
tags: ["Sports", "MCG", "Events", "Culture"]
},
{
id: 5,
title: "Foodie Paradise: Melbourne's Multicultural Dining Scene",
excerpt: "Experience Melbourne's incredible culinary diversity, from authentic Greek tavernas to innovative modern Australian cuisine in award-winning restaurants.",
image: "https://images.unsplash.com/photo-1681745623555-efc392301d6d?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w3Nzg4Nzd8MHwxfHNlYXJjaHwxfHxtZWxib3VybmUlMjBjb2ZmZWUlMjBjdWx0dXJlJTIwY2FmZXxlbnwxfHx8fDE3NTczMzkyNzJ8MA&ixlib=rb-4.1.0&q=80&w=1080&utm_source=figma&utm_medium=referral",
author: "Food Critic",
date: "Dec 5, 2024",
readTime: "8 min read",
category: "Food & Drink",
featured: false,
tags: ["Food", "Restaurants", "Multicultural", "Dining"]
},
{
id: 6,
title: "Melbourne After Dark: Rooftop Bars & Nightlife",
excerpt: "Explore Melbourne's sophisticated nightlife scene, from hidden speakeasies in historic buildings to stunning rooftop bars with panoramic city views.",
image: "https://images.unsplash.com/photo-1720347247737-9252d85d3027?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w3Nzg4Nzd8MHwxfHNlYXJjaHwxfHxtZWxib3VybmUlMjBjaXR5JTIwc2t5bGluZSUyMGZsaW5kZXJzJTIwc3RyZWV0fGVufDF8fHx8MTc1NzMzOTAyNHww&ixlib=rb-4.1.0&q=80&w=1080&utm_source=figma&utm_medium=referral",
author: "Nightlife Expert",
date: "Dec 2, 2024",
readTime: "5 min read",
category: "Nightlife",
featured: false,
tags: ["Nightlife", "Rooftop Bars", "Entertainment", "City Views"]
}
];
const categories = [
{ name: "All", count: 6, color: "from-gray-500 to-gray-600" },
{ name: "Culture", count: 2, color: "from-purple-500 to-pink-500" },
{ name: "Food & Drink", count: 2, color: "from-orange-500 to-red-500" },
{ name: "Nature", count: 1, color: "from-green-500 to-emerald-500" },
{ name: "Sports", count: 1, color: "from-blue-500 to-cyan-500" },
{ name: "Nightlife", count: 1, color: "from-indigo-500 to-purple-500" }
];
export function MelbourneBlogs() {
const sectionRef = useRef(null);
const navigate = useNavigate();
const featuredPost = blogPosts.find(post => post.featured);
const regularPosts = blogPosts.filter(post => !post.featured);
const cityName = localStorage.getItem('cityName');
return (
<section
ref={sectionRef}
className="py-20 bg-gradient-to-br from-gray-50 via-white to-gray-50 relative overflow-hidden"
> {/* Background Pattern */}
<div className="absolute inset-0 opacity-[0.02]">
<div className="absolute top-0 left-0 w-full h-full bg-gradient-to-br from-primary/20 via-secondary/20 to-primary/20"></div>
</div>
<div className="container mx-auto px-4 relative z-10">
{/* Header */}
<motion.div
initial={{ opacity: 0, y: 30 }}
whileInView={{ opacity: 1, y: 0 }}
transition={{ duration: 0.6 }}
viewport={{ once: true }}
className="text-center mb-16"
>
<div className="inline-flex items-center gap-2 bg-gradient-to-r from-primary/10 to-secondary/10 px-4 py-2 rounded-full mb-6">
<div className="w-2 h-2 bg-gradient-to-r from-primary to-secondary rounded-full"></div>
<span className="text-sm font-medium bg-gradient-to-r from-primary to-secondary bg-clip-text text-transparent">
{cityName} Stories
</span>
</div>
<h2 className="font-merchant text-4xl md:text-5xl lg:text-6xl text-gray-900 mb-6">
<span className="font-normal">{cityName}</span>{' '}
<span className="font-bold bg-gradient-to-r from-primary to-secondary bg-clip-text text-transparent italic pr-2">
Blogs
</span>
</h2>
<p className="text-xl text-gray-600 max-w-4xl mx-auto leading-relaxed">
Dive deep into {cityName}'s rich cultural tapestry, from hidden laneway treasures to world-renowned
coffee culture. Discover insider stories, local secrets, and expert guides to Australia's cultural capital
that will transform your {cityName} experience into an unforgettable journey.
</p>
</motion.div>
{/* Categories Filter */}
<motion.div
initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }}
transition={{ duration: 0.5, delay: 0.1 }}
viewport={{ once: true }}
className="flex flex-wrap justify-center gap-3 mb-16"
>
{categories.map((category, index) => (
<motion.button
key={category.name}
initial={{ opacity: 0, scale: 0.9 }}
whileInView={{ opacity: 1, scale: 1 }}
transition={{ duration: 0.4, delay: 0.2 + index * 0.05 }}
viewport={{ once: true }}
whileHover={{ scale: 1.05 }}
whileTap={{ scale: 0.95 }}
className={`px-6 py-3 rounded-full bg-gradient-to-r ${category.color} text-white font-medium shadow-lg hover:shadow-xl transition-all duration-300 group`}
>
<span className="flex items-center gap-2">
{category.name}
<span className="text-xs bg-white/20 px-2 py-1 rounded-full group-hover:bg-white/30 transition-colors duration-200">
{category.count}
</span>
</span>
</motion.button>
))}
</motion.div>
{/* Featured Post */}
{featuredPost && (
<motion.div
initial={{ opacity: 0, y: 30 }}
whileInView={{ opacity: 1, y: 0 }}
transition={{ duration: 0.6, delay: 0.2 }}
viewport={{ once: true }}
className="mb-16"
>
</motion.div>
)}
{/* Regular Blog Posts Grid */}
<div className="grid md:grid-cols-2 lg:grid-cols-3 gap-8">
{regularPosts.map((post, index) => (
<motion.article
key={post.id}
initial={{ opacity: 0, y: 30 }}
whileInView={{ opacity: 1, y: 0 }}
transition={{ duration: 0.5, delay: 0.3 + index * 0.1 }}
viewport={{ once: true }}
className="bg-white rounded-3xl shadow-lg overflow-hidden border border-gray-100 group hover:shadow-2xl hover:border-gray-200 transition-all duration-500 cursor-pointer h-[480px] flex flex-col"
>
{/* Post Image */}
<div className="relative overflow-hidden h-48">
<ImageWithFallback
src={post.image}
alt={post.title}
className="w-full h-full object-cover group-hover:scale-110 transition-transform duration-700"
/>
<div className="absolute inset-0 bg-gradient-to-t from-black/20 via-transparent to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-300"></div>
{/* Category Badge */}
<div className="absolute top-4 left-4 bg-white/95 backdrop-blur-sm text-gray-900 px-3 py-1 rounded-full text-xs font-medium">
{post.category}
</div>
</div>
{/* Post Content */}
<div className="p-6 flex-1 flex flex-col justify-between">
<div className="flex items-center gap-3 text-xs text-gray-500 mb-3">
<div className="flex items-center gap-1">
<User className="w-3 h-3" />
{post.author}
</div>
<div className="flex items-center gap-1">
<Calendar className="w-3 h-3" />
{post.date}
</div>
<div className="flex items-center gap-1">
<Clock className="w-3 h-3" />
{post.readTime}
</div>
</div>
<div className="flex-1 flex flex-col">
<h3 className="font-merchant text-xl font-semibold text-gray-900 mb-3 leading-tight group-hover:text-primary transition-colors duration-200 line-clamp-2">
{post.title}
</h3>
<p className="text-gray-600 leading-relaxed mb-4 text-sm flex-1 line-clamp-3">
{post.excerpt}
</p>
{/* Tags */}
<div className="flex flex-wrap gap-1 mb-4">
{post.tags.slice(0, 2).map((tag, tagIndex) => (
<span
key={tagIndex}
className="px-2 py-1 bg-gray-100 text-gray-600 rounded-full text-xs font-medium"
>
{tag}
</span>
))}
{post.tags.length > 2 && (
<span className="px-2 py-1 bg-gray-100 text-gray-600 rounded-full text-xs">
+{post.tags.length - 2}
</span>
)}
</div>
</div>
<div className="flex items-center justify-between mt-auto">
<span className="text-primary font-medium text-sm group-hover:text-secondary transition-colors duration-200">
Read More
</span>
<ArrowRight className="w-4 h-4 text-primary group-hover:text-secondary group-hover:translate-x-1 transition-all duration-200" />
</div>
</div>
</motion.article>
))}
</div>
{/* Call to Action */}
<motion.div
initial={{ opacity: 0, y: 30 }}
whileInView={{ opacity: 1, y: 0 }}
transition={{ duration: 0.6, delay: 0.5 }}
viewport={{ once: true }}
className="text-center mt-16"
>
<div className="bg-gradient-to-br from-primary/5 via-secondary/5 to-primary/5 rounded-3xl p-8 md:p-12 border border-gray-100">
<h3 className="font-merchant text-2xl md:text-3xl font-semibold text-gray-900 mb-4">
Want to explore {cityName} yourself?
</h3>
<p className="text-gray-600 text-lg mb-8 max-w-2xl mx-auto">
Get your {cityName} CityCard and unlock access to all these incredible experiences and more.
Start your adventure today with exclusive deals and insider access.
</p>
<div className="flex flex-col sm:flex-row gap-4 justify-center">
<Button
className="bg-gradient-to-r from-primary to-secondary text-white font-semibold px-8 py-4 rounded-2xl hover:scale-105 transition-all duration-300 shadow-lg hover:shadow-xl"
onClick={() => { navigate(`/${cityName.toLowerCase()}`), window.scrollTo({ top: 0, behavior: 'smooth' }); }}
>
<MapPin className="w-5 h-5 mr-2" />
Explore {cityName}
</Button>
<Button
variant="outline"
className="border-2 border-gray-300 text-gray-700 font-semibold px-8 py-4 rounded-2xl hover:border-primary hover:text-primary hover:scale-105 transition-all duration-300"
onClick={() => {
sectionRef.current?.scrollIntoView({
behavior: "smooth",
block: "start",
});
}}
>
<Coffee className="w-5 h-5 mr-2" />
View All Blogs
</Button>
</div>
</div>
</motion.div>
</div>
</section>
);
}