Files
no-copy-frontend/src/app/ui/search/file-search-panel.tsx
T

195 lines
6.5 KiB
TypeScript
Raw Normal View History

2026-01-28 12:12:23 +07:00
import { SearchedUserFilesList } from '@/app/ui/search/searched-user-files-list';
import { SearchedGlobalFilesList } from '@/app/ui/search/searched-global-files-list';
import { useCallback, useState, useImperativeHandle } from 'react';
2026-02-05 21:01:19 +07:00
import { searchUserFiles, searchGlobalFiles } from '@/app/actions/searchActions';
import { useQueryClient } from '@tanstack/react-query';
2026-01-28 12:12:23 +07:00
export function FileSearchPanel({ fileId, ref }: { fileId: string | null, ref: any }) {
const [searchedUserFiles, setSearchedUserFiles] = useState<string[]>([]);
2026-01-28 16:30:17 +07:00
const [searchedUserFilesShowNull, setSearchedUserFilesShowNull] = useState<boolean>(false);
2026-01-28 12:12:23 +07:00
const [searchedGlobalFiles, setSearchedGlobalFiles] = useState<string[]>([]);
2026-01-28 16:30:17 +07:00
const [searchedGlobalFilesShowNull, setSearchedGlobalFilesShowNull] = useState<boolean>(false);
2026-01-30 14:54:52 +07:00
const [loading, setLoading] = useState<boolean>(false);
2026-02-09 16:44:34 +07:00
const [showGlobalSearch, setShowGlobalSearch] = useState<boolean>(false);
2026-02-05 21:01:19 +07:00
const queryClient = useQueryClient();
2026-01-28 12:12:23 +07:00
useImperativeHandle(ref, () => ({
2026-01-28 16:30:17 +07:00
clearList: () => {
2026-01-28 12:12:23 +07:00
setSearchedUserFiles([]);
2026-01-28 16:30:17 +07:00
setSearchedGlobalFiles([]);
setSearchedUserFilesShowNull(false);
setSearchedGlobalFilesShowNull(false);
2026-02-09 16:44:34 +07:00
setShowGlobalSearch(false);
2026-01-28 12:12:23 +07:00
}
}));
const handlerSearchUserFile = useCallback(async (fileId: string): Promise<void> => {
try {
let result = await searchUserFiles(fileId);
if (result.content.length) {
setSearchedUserFiles(result.content);
2026-01-28 16:30:17 +07:00
} else {
setSearchedUserFilesShowNull(true);
2026-01-28 12:12:23 +07:00
}
} catch (error) {
}
2026-02-09 16:44:34 +07:00
setShowGlobalSearch(true);
handlerSearchGlobalFile(fileId)
2026-01-28 12:12:23 +07:00
}, [fileId])
const handlerSearchGlobalFile = useCallback(async (fileId: string): Promise<void> => {
2026-01-30 14:54:52 +07:00
setLoading(true);
setSearchedGlobalFilesShowNull(false);
setSearchedGlobalFiles([]);
2026-01-28 12:12:23 +07:00
try {
let result = await searchGlobalFiles(fileId);
2026-02-05 21:01:19 +07:00
console.log(result);
2026-01-28 12:12:23 +07:00
if (result.images.length) {
setSearchedGlobalFiles(result.images);
2026-01-28 16:30:17 +07:00
} else {
setSearchedGlobalFilesShowNull(true);
2026-01-28 12:12:23 +07:00
}
} catch (error) {
2026-01-30 14:54:52 +07:00
} finally {
2026-02-05 21:01:19 +07:00
await queryClient.invalidateQueries({ queryKey: ['userData'] });
await queryClient.invalidateQueries({ queryKey: ['userSearchData'] });
2026-01-30 14:54:52 +07:00
setLoading(false);
2026-01-28 12:12:23 +07:00
}
}, [fileId])
return (
<>
<div
className="mb-4"
>
<button
className="btn btn-primary btn-search"
disabled={fileId ? false : true}
onClick={() => {
if (fileId) {
handlerSearchUserFile(fileId)
}
}}
>
Начать поиск
</button>
</div>
{(searchedUserFiles.length !== 0) && (
<SearchedUserFilesList list={searchedUserFiles} />
2026-01-28 16:30:17 +07:00
)}
2026-01-28 12:12:23 +07:00
2026-01-28 16:30:17 +07:00
{searchedUserFilesShowNull && (
<div
className="user-file-search-results"
>
<div className="results-header">
<div className="results-title">Результаты поиска</div>
<div className="results-count">
Найдено файлов: {searchedUserFiles.length}
</div>
</div>
<div
className="empty-results"
>
<h3>Похожих файлов не найдено</h3>
<p>В вашей библиотеке нет файлов, похожих на загруженный</p>
<div className="empty-results-hint">
<strong>Совет:</strong> Убедитесь, что вы загружали этот файл ранее через страницу "Маркировка"
</div>
</div>
</div>
2026-01-28 12:12:23 +07:00
)}
2026-02-09 16:44:34 +07:00
{showGlobalSearch && (
<div
className="global-search-section"
>
<div className="global-search-header">
<div className="global-search-title">
Глобальный поиск изображений
</div>
<div className="">
Найти где ещё используется ваше изображение в интернете
</div>
<div className="global-search-badge">
Интернет поиск
</div>
2026-01-28 12:12:23 +07:00
</div>
2026-02-09 16:44:34 +07:00
<div className="global-search-content">
<div className="global-search-info">
<div className="global-search-info-title">
Поиск по всему интернету
</div>
<div className="global-search-info-text">
Используем продвинутые технологии обратного поиска по изображению для поиска копий вашего контента
на сайтах, в социальных сетях и других источниках. Поможет обнаружить несанкционированное использование.
</div>
</div>
<div className="search-counter" id="search-counter">
<div className="counter-info">
<div className="counter-icon" id="counter-icon"></div>
<div className="counter-text">
<div className="counter-label">Глобальных поисков сегодня</div>
<div className="counter-value" id="counter-value">0 из 10</div>
</div>
</div>
<div className="progress-bar">
<div
className="progress-fill"
id="progress-fill"
style={{ width: '0%' }}
>
</div>
</div>
</div>
<div className={`global-loading ${loading ? 'show' : ''}`} id="global-loading">
<div className="global-spinner"></div>
<div className="global-loading-text" id="global-loading-text">
Поиск изображений в интернете...
</div>
</div>
<div className={`global-result ${searchedGlobalFiles.length ? 'show' : ''}`} id="global-result">
<div className="global-result-card">
<div className="global-result-header">
<span>Найдено в интернете</span>
</div>
<div className="global-result-content">
<SearchedGlobalFilesList list={searchedGlobalFiles} />
</div>
</div>
</div>
{searchedGlobalFilesShowNull && (
<div className="global-no-result" id="global-no-result">
<div className="global-no-result-icon">&zwj;</div>
<h4>Похожие изображения в интернете не найдены</h4>
<p>Это может означать, что ваше изображение уникально и не используется на других сайтах.</p>
</div>
)}
<div className="global-error" id="global-error">
<strong>Ошибка глобального поиска:</strong>
<span id="global-error-text"></span>
</div>
2026-01-28 12:12:23 +07:00
</div>
</div>
2026-02-09 16:44:34 +07:00
)}
2026-01-28 12:12:23 +07:00
</>
)
}