This commit is contained in:
smanylov
2026-01-28 12:12:23 +07:00
parent f7f53d5af3
commit 2129fe1727
2 changed files with 167 additions and 163 deletions
+9 -163
View File
@@ -7,9 +7,7 @@ import { useTranslations } from 'next-intl';
import { useNavigationBlocker } from '@/app/hooks/useNavigationBlocker'; import { useNavigationBlocker } from '@/app/hooks/useNavigationBlocker';
import { useQueryClient } from '@tanstack/react-query'; import { useQueryClient } from '@tanstack/react-query';
import { searchUserFiles, removeUserFile, searchGlobalFiles } from '@/app/actions/fileEntity'; import { searchUserFiles, removeUserFile, searchGlobalFiles } from '@/app/actions/fileEntity';
import { SearchedUserFilesList } from '@/app/ui/search/searched-user-files-list'; import { FileSearchPanel } from '@/app/ui/search/file-search-panel';
import { SearchedGlobalFilesList } from '@/app/ui/search/searched-global-files-list';
import { useRouter } from 'next/navigation';
interface SelectedFile { interface SelectedFile {
file: File; file: File;
preview: string | undefined; preview: string | undefined;
@@ -40,12 +38,11 @@ export default function SectionSearchFile({ fileType, allowedExtensions, maxFile
const [isFileUploaded, setIsFileUploaded] = useState<boolean>(false); const [isFileUploaded, setIsFileUploaded] = useState<boolean>(false);
const [uploadProgress, setUploadProgress] = useState<number>(0); const [uploadProgress, setUploadProgress] = useState<number>(0);
const [fileId, setFileId] = useState<string | null>(null); const [fileId, setFileId] = useState<string | null>(null);
const [searchedUserFiles, setSearchedUserFiles] = useState<string[]>([]);
const [searchedGlobalFiles, setSearchedGlobalFiles] = useState<string[]>([]);
const queryClient = useQueryClient(); const queryClient = useQueryClient();
const isCancelledRef = useRef(false); const isCancelledRef = useRef(false);
const childRef = useRef(null);
const t = useTranslations('Global'); const t = useTranslations('Global');
const acceptString = useMemo(() => { const acceptString = useMemo(() => {
@@ -91,8 +88,11 @@ export default function SectionSearchFile({ fileType, allowedExtensions, maxFile
setError(null); setError(null);
setIsFileUploaded(false); setIsFileUploaded(false);
setSearchedUserFiles([]);
setSearchedGlobalFiles([]); if (childRef.current) {
//@ts-ignore
childRef.current.doSomething();
}
setUploadProgress(0); setUploadProgress(0);
@@ -151,23 +151,6 @@ export default function SectionSearchFile({ fileType, allowedExtensions, maxFile
handleFileSelect(file); handleFileSelect(file);
}; };
const handleClearFile = async (): Promise<void> => {
if (selectedFile && selectedFile.preview) {
URL.revokeObjectURL(selectedFile.preview);
}
if (uploadId) {
await cancelUpload(uploadId);
}
isCancelledRef.current = true;
setIsFileUploaded(false);
setSelectedFile(null);
setError(null);
setUploadProgress(0);
};
const handlerFileUpload = useCallback(async (fileInfo: SelectedFile): Promise<void> => { const handlerFileUpload = useCallback(async (fileInfo: SelectedFile): Promise<void> => {
if (uploadId) return; if (uploadId) return;
@@ -280,33 +263,6 @@ export default function SectionSearchFile({ fileType, allowedExtensions, maxFile
} }
}); });
const handlerSearchUserFile = useCallback(async (fileId: string): Promise<void> => {
try {
let result = await searchUserFiles(fileId);
if (result.content.length) {
setSearchedUserFiles(result.content);
}
} catch (error) {
}
}, [fileId])
const handlerSearchGlobalFile = useCallback(async (fileId: string): Promise<void> => {
try {
let result = await searchGlobalFiles(fileId);
if (result.images.length) {
setSearchedGlobalFiles(result.images);
}
} catch (error) {
}
}, [fileId])
return ( return (
<div className="upload-section"> <div className="upload-section">
<div className="search-info"> <div className="search-info">
@@ -381,117 +337,7 @@ export default function SectionSearchFile({ fileType, allowedExtensions, maxFile
</div> </div>
{isFileUploaded && ( {isFileUploaded && (
<> <FileSearchPanel fileId={fileId} ref={childRef} />
<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} />
)}
<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>
</div>
<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>
<button
type="button"
className="global-search-btn"
id="global-search-btn"
onClick={() => {
if (fileId) {
handlerSearchGlobalFile(fileId)
}
}}
>
Найти в интернете
</button>
<div className="global-loading" 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>
<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>
</div>
</div>
</>
)} )}
</div> </div>
); );
+158
View File
@@ -0,0 +1,158 @@
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';
import { searchUserFiles, searchGlobalFiles } from '@/app/actions/fileEntity';
export function FileSearchPanel({ fileId, ref }: { fileId: string | null, ref: any }) {
const [searchedUserFiles, setSearchedUserFiles] = useState<string[]>([]);
const [searchedGlobalFiles, setSearchedGlobalFiles] = useState<string[]>([]);
useImperativeHandle(ref, () => ({
doSomething: () => {
setSearchedUserFiles([]);
setSearchedGlobalFiles([])
}
}));
const handlerSearchUserFile = useCallback(async (fileId: string): Promise<void> => {
try {
let result = await searchUserFiles(fileId);
if (result.content.length) {
setSearchedUserFiles(result.content);
}
} catch (error) {
}
}, [fileId])
const handlerSearchGlobalFile = useCallback(async (fileId: string): Promise<void> => {
try {
let result = await searchGlobalFiles(fileId);
if (result.images.length) {
setSearchedGlobalFiles(result.images);
}
} catch (error) {
}
}, [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} />
)}
<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>
</div>
<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>
<button
type="button"
className="global-search-btn"
id="global-search-btn"
onClick={() => {
if (fileId) {
handlerSearchGlobalFile(fileId)
}
}}
>
Найти в интернете
</button>
<div className="global-loading" 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>
<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>
</div>
</div>
</>
)
}