+ {apiKeyValidated && apiKeyInfo && (
+
+ )}
+
+
+
+ {!apiKeyValidated && (
+
+ API Key
+
+
+
setApiKey(e.target.value)}
+ onKeyDown={(e) => {
+ if (e.key === 'Enter') {
+ e.preventDefault();
+ validateApiKey();
+ }
+ }}
+ placeholder="Enter your API key"
+ className="w-full px-4 py-3 bg-slate-800 border border-slate-700 rounded-lg text-white placeholder-gray-500 focus:outline-none focus:ring-2 focus:ring-amber-500 focus:border-transparent pr-12"
+ aria-label="API key input"
+ />
+
setApiKeyVisible(!apiKeyVisible)}
+ className="absolute right-3 top-1/2 -translate-y-1/2 p-2 text-gray-400 hover:text-white transition-colors focus:outline-none focus:ring-2 focus:ring-amber-500 rounded"
+ aria-label={apiKeyVisible ? 'Hide API key' : 'Show API key'}
+ >
+ {apiKeyVisible ? (
+
+
+
+ ) : (
+
+
+
+
+ )}
+
+
+
+ {validatingKey ? 'Validating...' : 'Validate'}
+
+
+
+ {apiKeyError && (
+
+
{apiKeyError}
+
+ {apiKeyError.includes('Invalid')
+ ? 'Please check your API key and try again. You can create a new key in the admin dashboard.'
+ : 'Please check your internet connection and try again.'}
+
+
+ )}
+
+ )}
+
+ {apiKeyValidated && (
+
+ {loading ? (
+
+ ) : error ? (
+
+
{error}
+
+ {error.includes('fetch') || error.includes('load')
+ ? 'Unable to load images. Please check your connection and try refreshing the page.'
+ : 'An error occurred while fetching your images. Please try again later.'}
+
+
+ ) : images.length === 0 ? (
+
+ ) : (
+ <>
+
+
+ {hasMore && (
+
+
+ {loadingMore ? (
+
+
+ Loading more images...
+
+ ) : (
+ 'Load More Images'
+ )}
+
+
+ )}
+ >
+ )}
+
+ )}
+
+
setZoomedImageUrl(null)} />
+
+ );
+}
diff --git a/apps/landing/src/components/demo/ImageZoomModal.tsx b/apps/landing/src/components/demo/ImageZoomModal.tsx
index 791bd7f..1f0d221 100644
--- a/apps/landing/src/components/demo/ImageZoomModal.tsx
+++ b/apps/landing/src/components/demo/ImageZoomModal.tsx
@@ -1,6 +1,6 @@
'use client';
-import { useEffect } from 'react';
+import { useEffect, useRef } from 'react';
interface ImageZoomModalProps {
imageUrl: string | null;
@@ -8,6 +8,9 @@ interface ImageZoomModalProps {
}
export const ImageZoomModal = ({ imageUrl, onClose }: ImageZoomModalProps) => {
+ const closeButtonRef = useRef