modify search function for all files search

This commit is contained in:
smanylov
2026-02-12 18:02:25 +07:00
parent f3e8ef3f65
commit a3da6b8530
5 changed files with 97 additions and 26 deletions
+22 -5
View File
@@ -2,7 +2,14 @@ import SectionSearchFile from '@/app/ui/search/section-search-file';
import { SupportedFormats } from '@/app/ui/search/supported-formats';
import { SearchStats } from '@/app/ui/search/search-stats';
import { RecentSearches } from '@/app/ui/search/recent-searches';
export default function Page() {
import { getAllowedFilesExtensions } from '@/app/actions/fileUpload';
export default async function Page() {
const { file_extension: extensionVideo, max_file_size } = await getAllowedFilesExtensions('video');
const { file_extension: extensionAudio } = await getAllowedFilesExtensions('audio');
const { file_extension: extensionImage } = await getAllowedFilesExtensions('image');
const { file_extension: extensionDocument } = await getAllowedFilesExtensions('document');
return (
<>
<div className="block-wrapper">
@@ -15,12 +22,22 @@ export default function Page() {
</div>
<div className="search-grid">
<SectionSearchFile
maxFileSize={1024000000}
allowedExtensions={['jpg', 'jpeg', 'png', 'gif', 'bmp']}
fileType="image"
maxFileSize={max_file_size}
/* allowedExtensions={allExtensions} */
allowedExtensions={{
images: extensionImage,
videos: extensionVideo,
audios: extensionAudio,
documents: extensionDocument
}}
/>
<div className="search-sidebar">
<SupportedFormats />
<SupportedFormats
extensionVideo={extensionVideo}
extensionAudio={extensionAudio}
extensionImage={extensionImage}
extensionDocument={extensionDocument}
/>
<SearchStats />
<RecentSearches />
</div>
+1
View File
@@ -3819,6 +3819,7 @@
color: v.$text-s;
font-size: 14px;
line-height: 1.5;
text-transform: uppercase;
}
.stat-item {
+11 -3
View File
@@ -23,6 +23,7 @@ export function FileSearchPanel({ fileId, ref }: { fileId: string | null, ref: a
const [paginationLoading, setPaginationLoading] = useState<boolean>(false);
const [showGlobalSearch, setShowGlobalSearch] = useState<boolean>(false);
const queryClient = useQueryClient();
const [errorMessage, setErrorMessage] = useState<string | null>(null);
const [searchTotalPages, setSearchTotalPages] = useState<number>(0);
const [searchCurrentPages, setSearchCurrentPages] = useState<number>(1);
@@ -41,20 +42,21 @@ export function FileSearchPanel({ fileId, ref }: { fileId: string | null, ref: a
const handlerSearchUserFile = useCallback(async (fileId: string, page: number): Promise<void> => {
setErrorMessage(null);
try {
let result = await searchUserFiles(fileId);
if (result.content.length) {
setSearchedUserFiles(result.content);
setShowGlobalSearch(true);
handlerSearchGlobalFile(fileId, page)
} else {
setSearchedUserFilesShowNull(true);
}
} catch (error) {
setErrorMessage('error');
}
setShowGlobalSearch(true);
handlerSearchGlobalFile(fileId, page)
}, [fileId])
@@ -106,6 +108,12 @@ export function FileSearchPanel({ fileId, ref }: { fileId: string | null, ref: a
>
Начать поиск
</button>
{errorMessage && (
<div className='mt-2 text-red-600 text-sm'>
Ошибка поиска
</div>
)}
</div>
{(searchedUserFiles.length !== 0) && (
+47 -10
View File
@@ -24,12 +24,16 @@ interface FileUploadInitResponse {
}
interface SectionSearchFile {
fileType: string
allowedExtensions: string[]
allowedExtensions: {
images: string[],
videos: string[],
audios: string[],
documents: string[]
}
maxFileSize: number
}
export default function SectionSearchFile({ fileType, allowedExtensions, maxFileSize }: SectionSearchFile) {
export default function SectionSearchFile({ allowedExtensions, maxFileSize }: SectionSearchFile) {
const fileInputRef = useRef<HTMLInputElement>(null);
const [isDragging, setIsDragging] = useState<boolean>(false);
const [selectedFile, setSelectedFile] = useState<SelectedFile | null>(null);
@@ -45,17 +49,49 @@ export default function SectionSearchFile({ fileType, allowedExtensions, maxFile
const t = useTranslations('Global');
const allExtensions = useMemo(() => { return [...allowedExtensions.images, ...allowedExtensions.videos, ...allowedExtensions.audios, ...allowedExtensions.documents] }, []);
const acceptString = useMemo(() => {
if (!allowedExtensions || !Array.isArray(allowedExtensions)) {
if (!allExtensions || !Array.isArray(allExtensions)) {
return '';
}
return allowedExtensions.map(e => `.${e}`).join(', ');
}, [allowedExtensions]);
return allExtensions.map(e => `.${e}`).join(', ');
}, [allExtensions]);
const getFileType = (fileName: string, allowedExtensions: {
images: string[],
videos: string[],
audios: string[],
documents: string[]
}): 'image' | 'video' | 'audio' | 'document' | 'unknown' => {
const lastDotIndex = fileName.lastIndexOf('.');
const extension = fileName.substring(lastDotIndex + 1).toLowerCase();
if (allowedExtensions.images.includes(extension)) {
return 'image';
}
if (allowedExtensions.videos.includes(extension)) {
return 'video';
}
if (allowedExtensions.audios.includes(extension)) {
return 'audio';
}
if (allowedExtensions.documents.includes(extension)) {
return 'document';
}
return 'unknown';
}
const validateFile = (file: File): { isValid: boolean; errorMessage?: string } => {
if (!allowedExtensions.includes(file.type as string)) {
if (!allExtensions.includes(file.type as string)) {
const extension = file.name.split('.').pop()?.toLowerCase();
if (!extension || !allowedExtensions.includes(extension as string)) {
if (!extension || !allExtensions.includes(extension as string)) {
return {
isValid: false,
errorMessage: t('unsupported-file-format')
@@ -117,7 +153,7 @@ export default function SectionSearchFile({ fileType, allowedExtensions, maxFile
preview: file.size < 10 * 1024 * 1024 ? URL.createObjectURL(file) : undefined
});
}, [fileType, t]);
}, [t]);
const handleFileInputChange = (event: ChangeEvent<HTMLInputElement>): void => {
const file = event.target.files?.[0] || null;
@@ -157,6 +193,7 @@ export default function SectionSearchFile({ fileType, allowedExtensions, maxFile
setError(null);
isCancelledRef.current = false;
const file = fileInfo.file;
const fileType = getFileType(fileInfo.file.name, allowedExtensions);
try {
const extension = file.name.split('.').pop() || '';
@@ -225,7 +262,7 @@ export default function SectionSearchFile({ fileType, allowedExtensions, maxFile
} finally {
setUploadId(null);
}
}, [uploadId, fileType]);
}, [uploadId, allowedExtensions]);
useEffect(() => {
// Обработка закрытия вкладки
+16 -8
View File
@@ -1,5 +1,13 @@
import { IconImageFile, IconVideoFile, IconAudioFile, IconDocument } from '@/app/ui/icons/icons';
export function SupportedFormats() {
interface supportedFormats {
extensionVideo: string[]
extensionAudio: string[]
extensionImage: string[]
extensionDocument: string[]
}
export function SupportedFormats({ extensionVideo, extensionAudio, extensionImage, extensionDocument }: supportedFormats) {
return (
<div className="supported-formats">
<div className="formats-title">
@@ -11,34 +19,34 @@ export function SupportedFormats() {
<IconImageFile /> Изображения
</div>
<div className="format-list">
JPEG, PNG, GIF, BMP
{extensionImage.join(', ')}
</div>
</div>
<div className="format-group hidden">
<div className="format-group">
<div className="format-type video">
<IconVideoFile /> Видео
</div>
<div className="format-list">
MP4, AVI, MOV, WMV
{extensionVideo.join(', ')}
</div>
</div>
<div className="format-group hidden">
<div className="format-group">
<div className="format-type audio">
<IconAudioFile /> Аудио
</div>
<div className="format-list">
MP3, WAV, FLAC, AAC
{extensionAudio.join(', ')}
</div>
</div>
<div className="format-group hidden">
<div className="format-group">
<div className="format-type document">
<IconDocument /> Документы
</div>
<div className="format-list">
PDF, DOC, DOCX
{extensionDocument.join(', ')}
</div>
</div>
</div>