2024-04-09 16:21:05 +05:30
|
|
|
/* eslint-disable @next/next/no-img-element */
|
|
|
|
import { ImagesIcon, PlusIcon } from 'lucide-react';
|
|
|
|
import { useState } from 'react';
|
|
|
|
import Lightbox from 'yet-another-react-lightbox';
|
|
|
|
import 'yet-another-react-lightbox/styles.css';
|
2024-04-28 11:15:28 +05:30
|
|
|
import { Message } from './ChatWindow';
|
2024-04-09 16:21:05 +05:30
|
|
|
|
|
|
|
type Image = {
|
|
|
|
url: string;
|
|
|
|
img_src: string;
|
|
|
|
title: string;
|
|
|
|
};
|
|
|
|
|
2024-04-28 11:15:28 +05:30
|
|
|
const SearchImages = ({
|
|
|
|
query,
|
2024-10-30 10:28:31 +05:30
|
|
|
chatHistory,
|
2024-04-28 11:15:28 +05:30
|
|
|
}: {
|
|
|
|
query: string;
|
2024-10-30 10:28:31 +05:30
|
|
|
chatHistory: Message[];
|
2024-04-28 11:15:28 +05:30
|
|
|
}) => {
|
2024-04-09 16:21:05 +05:30
|
|
|
const [images, setImages] = useState<Image[] | null>(null);
|
|
|
|
const [loading, setLoading] = useState(false);
|
|
|
|
const [open, setOpen] = useState(false);
|
|
|
|
const [slides, setSlides] = useState<any[]>([]);
|
|
|
|
|
2024-12-30 13:34:26 +01:00
|
|
|
const handleSearch = async () => {
|
|
|
|
setLoading(true);
|
|
|
|
try {
|
|
|
|
console.log("🖼️ Démarrage de la recherche d'images pour:", query);
|
|
|
|
|
|
|
|
const chatModelProvider = localStorage.getItem('chatModelProvider');
|
|
|
|
const chatModel = localStorage.getItem('chatModel');
|
|
|
|
console.log("🖼️ Modèle configuré:", chatModelProvider, chatModel);
|
|
|
|
|
|
|
|
const response = await fetch('/api/images', {
|
|
|
|
method: 'POST',
|
|
|
|
headers: {
|
|
|
|
'Content-Type': 'application/json',
|
|
|
|
},
|
|
|
|
body: JSON.stringify({
|
|
|
|
query: query,
|
|
|
|
chatHistory: chatHistory,
|
|
|
|
chatModel: {
|
|
|
|
provider: chatModelProvider,
|
|
|
|
model: chatModel,
|
|
|
|
},
|
|
|
|
}),
|
|
|
|
});
|
|
|
|
|
|
|
|
if (!response.ok) {
|
|
|
|
throw new Error(`HTTP error! status: ${response.status}`);
|
|
|
|
}
|
|
|
|
|
|
|
|
const data = await response.json();
|
|
|
|
console.log('🖼️ Résultats de la recherche:', data);
|
|
|
|
|
|
|
|
if (data.images && data.images.length > 0) {
|
|
|
|
setImages(data.images);
|
|
|
|
setSlides(
|
|
|
|
data.images.map((image: Image) => ({
|
|
|
|
src: image.img_src,
|
|
|
|
}))
|
|
|
|
);
|
|
|
|
console.log('🖼️ Images et slides mis à jour:', data.images.length);
|
|
|
|
} else {
|
|
|
|
console.log('🖼️ Aucune image trouvée');
|
|
|
|
}
|
|
|
|
} catch (error) {
|
|
|
|
console.error('🖼️ Erreur lors de la recherche:', error);
|
|
|
|
} finally {
|
|
|
|
setLoading(false);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2024-04-09 16:21:05 +05:30
|
|
|
return (
|
|
|
|
<>
|
|
|
|
{!loading && images === null && (
|
|
|
|
<button
|
2024-12-30 13:34:26 +01:00
|
|
|
onClick={handleSearch}
|
2024-05-29 14:44:25 +08:00
|
|
|
className="border border-dashed border-light-200 dark:border-dark-200 hover:bg-light-200 dark:hover:bg-dark-200 active:scale-95 duration-200 transition px-4 py-2 flex flex-row items-center justify-between rounded-lg dark:text-white text-sm w-full"
|
2024-04-09 16:21:05 +05:30
|
|
|
>
|
|
|
|
<div className="flex flex-row items-center space-x-2">
|
|
|
|
<ImagesIcon size={17} />
|
|
|
|
<p>Search images</p>
|
|
|
|
</div>
|
|
|
|
<PlusIcon className="text-[#24A0ED]" size={17} />
|
|
|
|
</button>
|
|
|
|
)}
|
|
|
|
{loading && (
|
2024-04-30 14:26:17 +05:30
|
|
|
<div className="grid grid-cols-2 gap-2">
|
2024-04-09 16:21:05 +05:30
|
|
|
{[...Array(4)].map((_, i) => (
|
|
|
|
<div
|
|
|
|
key={i}
|
2024-05-27 11:49:09 +08:00
|
|
|
className="bg-light-secondary dark:bg-dark-secondary h-32 w-full rounded-lg animate-pulse aspect-video object-cover"
|
2024-04-09 16:21:05 +05:30
|
|
|
/>
|
|
|
|
))}
|
|
|
|
</div>
|
|
|
|
)}
|
|
|
|
{images !== null && images.length > 0 && (
|
|
|
|
<>
|
|
|
|
<div className="grid grid-cols-2 gap-2">
|
|
|
|
{images.length > 4
|
|
|
|
? images.slice(0, 3).map((image, i) => (
|
|
|
|
<img
|
|
|
|
onClick={() => {
|
|
|
|
setOpen(true);
|
|
|
|
setSlides([
|
|
|
|
slides[i],
|
|
|
|
...slides.slice(0, i),
|
|
|
|
...slides.slice(i + 1),
|
|
|
|
]);
|
|
|
|
}}
|
|
|
|
key={i}
|
|
|
|
src={image.img_src}
|
|
|
|
alt={image.title}
|
2024-04-30 12:39:04 +05:30
|
|
|
className="h-full w-full aspect-video object-cover rounded-lg transition duration-200 active:scale-95 hover:scale-[1.02] cursor-zoom-in"
|
2024-04-09 16:21:05 +05:30
|
|
|
/>
|
|
|
|
))
|
|
|
|
: images.map((image, i) => (
|
|
|
|
<img
|
|
|
|
onClick={() => {
|
|
|
|
setOpen(true);
|
|
|
|
setSlides([
|
|
|
|
slides[i],
|
|
|
|
...slides.slice(0, i),
|
|
|
|
...slides.slice(i + 1),
|
|
|
|
]);
|
|
|
|
}}
|
|
|
|
key={i}
|
|
|
|
src={image.img_src}
|
|
|
|
alt={image.title}
|
2024-04-30 12:39:04 +05:30
|
|
|
className="h-full w-full aspect-video object-cover rounded-lg transition duration-200 active:scale-95 hover:scale-[1.02] cursor-zoom-in"
|
2024-04-09 16:21:05 +05:30
|
|
|
/>
|
|
|
|
))}
|
|
|
|
{images.length > 4 && (
|
|
|
|
<button
|
|
|
|
onClick={() => setOpen(true)}
|
2024-05-28 10:15:42 +08:00
|
|
|
className="bg-light-100 hover:bg-light-200 dark:bg-dark-100 dark:hover:bg-dark-200 transition duration-200 active:scale-95 hover:scale-[1.02] h-auto w-full rounded-lg flex flex-col justify-between text-white p-2"
|
2024-04-09 16:21:05 +05:30
|
|
|
>
|
|
|
|
<div className="flex flex-row items-center space-x-1">
|
|
|
|
{images.slice(3, 6).map((image, i) => (
|
|
|
|
<img
|
|
|
|
key={i}
|
|
|
|
src={image.img_src}
|
|
|
|
alt={image.title}
|
|
|
|
className="h-6 w-12 rounded-md lg:h-3 lg:w-6 lg:rounded-sm aspect-video object-cover"
|
|
|
|
/>
|
|
|
|
))}
|
|
|
|
</div>
|
2024-05-24 20:29:49 +08:00
|
|
|
<p className="text-black/70 dark:text-white/70 text-xs">
|
2024-04-30 14:26:17 +05:30
|
|
|
View {images.length - 3} more
|
2024-04-09 16:21:05 +05:30
|
|
|
</p>
|
|
|
|
</button>
|
|
|
|
)}
|
|
|
|
</div>
|
|
|
|
<Lightbox open={open} close={() => setOpen(false)} slides={slides} />
|
|
|
|
</>
|
|
|
|
)}
|
|
|
|
</>
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
export default SearchImages;
|