willytpfw's picture
puedes corregir el error ?
dac72ca verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>PixelFlow Carousel</title>
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script>
<style>
.zoom-effect {
transition: transform 0.3s ease;
}
.zoom-effect:hover {
transform: scale(1.03);
}
.skeleton {
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 .skeleton {
background: linear-gradient(90deg, #2d3748 25%, #4a5568 50%, #2d3748 75%);
}
.carousel-transition {
transition: opacity 0.5s ease, transform 0.5s ease;
}
</style>
</head>
<body class="bg-white dark:bg-gray-900 transition-colors duration-300">
<div id="root"></div>
<script type="text/babel">
const { useState, useEffect, useRef } = React;
const ImageCarousel = () => {
const [images, setImages] = useState([]);
const [currentIndex, setCurrentIndex] = useState(0);
const [isLoading, setIsLoading] = useState(true);
const [error, setError] = useState(null);
const [isAutoPlaying, setIsAutoPlaying] = useState(true);
const [apiSource, setApiSource] = useState('unsplash');
const [darkMode, setDarkMode] = useState(false);
const timerRef = useRef(null);
const carouselRef = useRef(null);
const API_CONFIG = {
unsplash: {
url: '',
params: {},
transform: () => []
},
pexels: {
url: '',
params: {},
transform: () => []
},
pixabay: {
url: '',
params: {},
transform: () => []
}
};
const fetchImages = async () => {
setIsLoading(true);
setError(null);
try {
const config = API_CONFIG[apiSource];
// Skip API calls and use placeholders directly since API keys aren't provided
setImages(Array(5).fill().map((_, i) => ({
url: `http://static.photos/nature/1024x576/${i+1}`,
alt: `Placeholder Image ${i+1}`,
author: 'Placeholder Author',
authorUrl: '#'
})));
return;
const data = await response.json();
if (!response.ok) throw new Error(data.message || 'Failed to fetch images');
setImages(config.transform(data));
} catch (err) {
console.error('Error fetching images:', err);
setError(err.message || 'Failed to load images. Please try again.');
// Fallback to placeholder images
setImages(Array(5).fill().map((_, i) => ({
url: `http://static.photos/nature/1024x576/${i+1}`,
alt: `Placeholder Image ${i+1}`,
author: 'Placeholder Author',
authorUrl: '#'
})));
} finally {
setIsLoading(false);
}
};
useEffect(() => {
fetchImages();
}, [apiSource]);
useEffect(() => {
if (isAutoPlaying && images.length > 0) {
timerRef.current = setInterval(() => {
setCurrentIndex(prev => (prev + 1) % images.length);
}, 5000);
}
return () => clearInterval(timerRef.current);
}, [isAutoPlaying, images.length]);
const goToPrev = () => {
setCurrentIndex(prev => (prev - 1 + images.length) % images.length);
resetTimer();
};
const goToNext = () => {
setCurrentIndex(prev => (prev + 1) % images.length);
resetTimer();
};
const goToIndex = (index) => {
setCurrentIndex(index);
resetTimer();
};
const resetTimer = () => {
if (isAutoPlaying) {
clearInterval(timerRef.current);
timerRef.current = setInterval(() => {
setCurrentIndex(prev => (prev + 1) % images.length);
}, 5000);
}
};
const toggleAutoPlay = () => {
setIsAutoPlaying(prev => !prev);
};
const toggleDarkMode = () => {
setDarkMode(prev => !prev);
document.body.classList.toggle('dark');
};
if (error) {
return (
<div className="flex flex-col items-center justify-center min-h-screen p-4">
<div className="bg-red-100 dark:bg-red-900 text-red-800 dark:text-red-200 p-4 rounded-lg max-w-md">
<div className="flex items-center">
<i data-feather="alert-triangle" className="mr-2"></i>
<h3 className="font-bold">Error Loading Images</h3>
</div>
<p className="mt-2">{error}</p>
<p className="mt-2 text-sm">Using static placeholder images.</p>
<button
onClick={fetchImages}
className="mt-4 bg-red-500 hover:bg-red-600 text-white px-4 py-2 rounded-md transition-colors"
>
Retry
</button>
</div>
</div>
);
}
return (
<div className="min-h-screen flex flex-col items-center justify-center p-4">
<div className="w-full max-w-4xl">
<div className="flex justify-between items-center mb-6">
<h1 className="text-3xl font-bold text-gray-800 dark:text-white">PixelFlow Carousel</h1>
<div className="flex space-x-4">
<div className="bg-gray-100 dark:bg-gray-700 text-gray-800 dark:text-white px-3 py-2 rounded-md">
Static Photos
</div>
<button
onClick={toggleDarkMode}
className="p-2 rounded-full bg-gray-200 dark:bg-gray-700 text-gray-700 dark:text-gray-200"
>
<i data-feather={darkMode ? "sun" : "moon"}></i>
</button>
</div>
</div>
<div className="relative overflow-hidden rounded-xl shadow-xl">
{isLoading ? (
<div className="aspect-video w-full skeleton rounded-xl"></div>
) : (
<div
ref={carouselRef}
className="relative aspect-video w-full overflow-hidden"
>
{images.map((image, index) => (
<div
key={index}
className={`absolute inset-0 flex items-center justify-center carousel-transition ${index === currentIndex ? 'opacity-100' : 'opacity-0 pointer-events-none'}`}
>
<div className="relative w-full h-full group">
<img
src={image.url}
alt={image.alt}
className="w-full h-full object-cover zoom-effect"
/>
<div className="absolute inset-0 bg-black bg-opacity-0 group-hover:bg-opacity-30 transition-all duration-300 flex items-end p-6">
<div className="transform translate-y-8 group-hover:translate-y-0 transition-transform duration-300">
<h3 className="text-white text-xl font-bold">{image.alt}</h3>
<a
href={image.authorUrl}
target="_blank"
rel="noopener noreferrer"
className="text-gray-200 hover:text-white text-sm"
>
Photo by {image.author}
</a>
</div>
</div>
</div>
</div>
))}
</div>
)}
{/* Navigation Arrows */}
<button
onClick={goToPrev}
className="absolute left-4 top-1/2 -translate-y-1/2 bg-white dark:bg-gray-800 bg-opacity-80 dark:bg-opacity-80 p-2 rounded-full shadow-md hover:bg-opacity-100 transition-all"
disabled={isLoading}
>
<i data-feather="chevron-left" className="text-gray-800 dark:text-white"></i>
</button>
<button
onClick={goToNext}
className="absolute right-4 top-1/2 -translate-y-1/2 bg-white dark:bg-gray-800 bg-opacity-80 dark:bg-opacity-80 p-2 rounded-full shadow-md hover:bg-opacity-100 transition-all"
disabled={isLoading}
>
<i data-feather="chevron-right" className="text-gray-800 dark:text-white"></i>
</button>
{/* Indicators */}
<div className="absolute bottom-4 left-0 right-0 flex justify-center space-x-2">
{images.map((_, index) => (
<button
key={index}
onClick={() => goToIndex(index)}
className={`w-3 h-3 rounded-full ${index === currentIndex ? 'bg-white' : 'bg-white bg-opacity-50'} transition-all`}
disabled={isLoading}
></button>
))}
</div>
{/* Play/Pause Button */}
<button
onClick={toggleAutoPlay}
className="absolute top-4 right-4 bg-white dark:bg-gray-800 bg-opacity-80 dark:bg-opacity-80 p-2 rounded-full shadow-md hover:bg-opacity-100 transition-all"
>
<i data-feather={isAutoPlaying ? "pause" : "play"} className="text-gray-800 dark:text-white"></i>
</button>
</div>
<div className="mt-6 text-center text-gray-600 dark:text-gray-400">
<p>Browse the static image carousel using navigation controls</p>
<div className="mt-2 flex justify-center space-x-4">
<button
onClick={fetchImages}
className="flex items-center text-sm bg-gray-100 dark:bg-gray-700 px-3 py-1 rounded-md"
>
<i data-feather="refresh-cw" className="w-4 h-4 mr-1"></i>
Refresh Images
</button>
</div>
</div>
</div>
</div>
);
};
const App = () => {
return (
<div>
<ImageCarousel />
</div>
);
};
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);
// Initialize feather icons
feather.replace();
</script>
</body>
</html>