Spaces:
Running
on
CPU Upgrade
Running
on
CPU Upgrade
| 'use client'; | |
| import { useEffect, useState, use, useMemo } from 'react'; | |
| import { LuImageOff, LuLoader, LuBan } from 'react-icons/lu'; | |
| import { FaChevronLeft } from 'react-icons/fa'; | |
| import DatasetImageCard from '@/components/DatasetImageCard'; | |
| import { Button } from '@headlessui/react'; | |
| import AddImagesModal, { openImagesModal } from '@/components/AddImagesModal'; | |
| import { TopBar, MainContent } from '@/components/layout'; | |
| import { apiClient } from '@/utils/api'; | |
| import FullscreenDropOverlay from '@/components/FullscreenDropOverlay'; | |
| import { useRouter } from 'next/navigation'; | |
| import { usingBrowserDb } from '@/utils/env'; | |
| import { hasUserDataset } from '@/utils/storage/datasetStorage'; | |
| import { useAuth } from '@/contexts/AuthContext'; | |
| import HFLoginButton from '@/components/HFLoginButton'; | |
| import Link from 'next/link'; | |
| export default function DatasetPage({ params }: { params: { datasetName: string } }) { | |
| const [imgList, setImgList] = useState<{ img_path: string }[]>([]); | |
| const usableParams = use(params as any) as { datasetName: string }; | |
| const datasetName = usableParams.datasetName; | |
| const [status, setStatus] = useState<'idle' | 'loading' | 'success' | 'error'>('idle'); | |
| const router = useRouter(); | |
| const { status: authStatus } = useAuth(); | |
| const isAuthenticated = authStatus === 'authenticated'; | |
| const hasDatasetEntry = !usingBrowserDb || hasUserDataset(datasetName); | |
| const allowAccess = hasDatasetEntry && isAuthenticated; | |
| const refreshImageList = (dbName: string) => { | |
| setStatus('loading'); | |
| console.log('Fetching images for dataset:', dbName); | |
| apiClient | |
| .post('/api/datasets/listImages', { datasetName: dbName }) | |
| .then((res: any) => { | |
| const data = res.data; | |
| console.log('Images:', data.images); | |
| // sort | |
| data.images.sort((a: { img_path: string }, b: { img_path: string }) => a.img_path.localeCompare(b.img_path)); | |
| setImgList(data.images); | |
| setStatus('success'); | |
| }) | |
| .catch(error => { | |
| console.error('Error fetching images:', error); | |
| setStatus('error'); | |
| }); | |
| }; | |
| useEffect(() => { | |
| if (!datasetName) { | |
| return; | |
| } | |
| if (!isAuthenticated) { | |
| return; | |
| } | |
| if (!hasDatasetEntry) { | |
| setImgList([]); | |
| setStatus('error'); | |
| router.replace('/datasets'); | |
| return; | |
| } | |
| refreshImageList(datasetName); | |
| }, [datasetName, hasDatasetEntry, isAuthenticated, router]); | |
| if (!allowAccess) { | |
| return ( | |
| <> | |
| <TopBar> | |
| <div> | |
| <Button className="text-gray-500 dark:text-gray-300 px-3 mt-1" onClick={() => history.back()}> | |
| <FaChevronLeft /> | |
| </Button> | |
| </div> | |
| <div> | |
| <h1 className="text-lg">Dataset: {datasetName}</h1> | |
| </div> | |
| <div className="flex-1"></div> | |
| </TopBar> | |
| <MainContent> | |
| <div className="border border-gray-800 rounded-lg p-6 bg-gray-900 text-gray-400 text-sm flex flex-col gap-4"> | |
| <p>You need to sign in with Hugging Face or provide a valid token to view this dataset.</p> | |
| <div className="flex items-center gap-3"> | |
| <HFLoginButton size="sm" /> | |
| <Link href="/settings" className="text-xs text-blue-400 hover:text-blue-300"> | |
| Manage authentication in Settings | |
| </Link> | |
| </div> | |
| </div> | |
| </MainContent> | |
| </> | |
| ); | |
| } | |
| const PageInfoContent = useMemo(() => { | |
| let icon = null; | |
| let text = ''; | |
| let subtitle = ''; | |
| let showIt = false; | |
| let bgColor = ''; | |
| let textColor = ''; | |
| let iconColor = ''; | |
| if (status == 'loading') { | |
| icon = <LuLoader className="animate-spin w-8 h-8" />; | |
| text = 'Loading Images'; | |
| subtitle = 'Please wait while we fetch your dataset images...'; | |
| showIt = true; | |
| bgColor = 'bg-gray-50 dark:bg-gray-800/50'; | |
| textColor = 'text-gray-900 dark:text-gray-100'; | |
| iconColor = 'text-gray-500 dark:text-gray-400'; | |
| } | |
| if (status == 'error') { | |
| icon = <LuBan className="w-8 h-8" />; | |
| text = 'Error Loading Images'; | |
| subtitle = 'There was a problem fetching the images. Please try refreshing the page.'; | |
| showIt = true; | |
| bgColor = 'bg-red-50 dark:bg-red-950/20'; | |
| textColor = 'text-red-900 dark:text-red-100'; | |
| iconColor = 'text-red-600 dark:text-red-400'; | |
| } | |
| if (status == 'success' && imgList.length === 0) { | |
| icon = <LuImageOff className="w-8 h-8" />; | |
| text = 'No Images Found'; | |
| subtitle = 'This dataset is empty. Click "Add Images" to get started.'; | |
| showIt = true; | |
| bgColor = 'bg-gray-50 dark:bg-gray-800/50'; | |
| textColor = 'text-gray-900 dark:text-gray-100'; | |
| iconColor = 'text-gray-500 dark:text-gray-400'; | |
| } | |
| if (!showIt) return null; | |
| return ( | |
| <div | |
| className={`mt-10 flex flex-col items-center justify-center py-16 px-8 rounded-xl border-2 border-gray-700 border-dashed ${bgColor} ${textColor} mx-auto max-w-md text-center`} | |
| > | |
| <div className={`${iconColor} mb-4`}>{icon}</div> | |
| <h3 className="text-lg font-semibold mb-2">{text}</h3> | |
| <p className="text-sm opacity-75 leading-relaxed">{subtitle}</p> | |
| </div> | |
| ); | |
| }, [status, imgList.length]); | |
| return ( | |
| <> | |
| {/* Fixed top bar */} | |
| <TopBar> | |
| <div> | |
| <Button className="text-gray-500 dark:text-gray-300 px-3 mt-1" onClick={() => history.back()}> | |
| <FaChevronLeft /> | |
| </Button> | |
| </div> | |
| <div> | |
| <h1 className="text-lg">Dataset: {datasetName}</h1> | |
| </div> | |
| <div className="flex-1"></div> | |
| <div> | |
| <Button | |
| className="text-gray-200 bg-slate-600 px-3 py-1 rounded-md" | |
| onClick={() => openImagesModal(datasetName, () => refreshImageList(datasetName))} | |
| > | |
| Add Images | |
| </Button> | |
| </div> | |
| </TopBar> | |
| <MainContent> | |
| {PageInfoContent} | |
| {status === 'success' && imgList.length > 0 && ( | |
| <div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4"> | |
| {imgList.map(img => ( | |
| <DatasetImageCard | |
| key={img.img_path} | |
| alt="image" | |
| imageUrl={img.img_path} | |
| onDelete={() => refreshImageList(datasetName)} | |
| /> | |
| ))} | |
| </div> | |
| )} | |
| </MainContent> | |
| <AddImagesModal /> | |
| <FullscreenDropOverlay | |
| datasetName={datasetName} | |
| onComplete={() => refreshImageList(datasetName)} | |
| /> | |
| </> | |
| ); | |
| } | |