import { useCallback, useMemo, useState } from 'react' import { useDropzone } from 'react-dropzone' import { Button, ScrollArea } from '@janhq/uikit' import { useAtomValue, useSetAtom } from 'jotai' import { Plus, UploadCloudIcon } from 'lucide-react' import { twMerge } from 'tailwind-merge' import useDropModelBinaries from '@/hooks/useDropModelBinaries' import { setImportModelStageAtom } from '@/hooks/useImportModel' import ModelSearch from './ModelSearch' import RowModel from './Row' import { downloadedModelsAtom } from '@/helpers/atoms/Model.atom' const Column = ['Name', 'Model ID', 'Size', 'Version', 'Status', ''] const Models: React.FC = () => { const downloadedModels = useAtomValue(downloadedModelsAtom) const setImportModelStage = useSetAtom(setImportModelStageAtom) const { onDropModels } = useDropModelBinaries() const [searchText, setSearchText] = useState('') const filteredDownloadedModels = useMemo( () => downloadedModels .filter((e) => e.name.toLowerCase().includes(searchText.toLowerCase().trim()) ) .sort((a, b) => a.name.localeCompare(b.name)), [downloadedModels, searchText] ) const { getRootProps, isDragActive } = useDropzone({ noClick: true, multiple: true, onDrop: onDropModels, }) const onImportModelClick = useCallback(() => { setImportModelStage('SELECTING_MODEL') }, [setImportModelStage]) const onSearchChange = useCallback((input: string) => { setSearchText(input) }, []) return ( {isDragActive && (
Drop file here

File (GGUF) or folder

)}
{Column.map((col) => ( ))} {filteredDownloadedModels ? filteredDownloadedModels.map((x) => ( )) : null}
{col}
) } export default Models