add null result for search files

This commit is contained in:
smanylov
2026-01-28 16:30:17 +07:00
parent efae068bac
commit a6a493fe97
5 changed files with 85 additions and 31 deletions
+1 -1
View File
@@ -1,4 +1,4 @@
import SectionSearchFile from '@/app/components/section-search-file';
import SectionSearchFile from '@/app/ui/search/section-search-file';
export default function Page() {
return (
<>
+24 -4
View File
@@ -3125,7 +3125,6 @@
}
.global-no-result {
display: none;
text-align: center;
padding: 60px 20px;
background: #f8fafc;
@@ -3199,6 +3198,20 @@
}
}
.empty-results {
text-align: center;
padding: 60px 20px;
color: #64748b;
&-hint {
margin-top: 16px;
padding: 12px;
background: #f0f9ff;
border-radius: 8px;
font-size: 14px;
}
}
.results-list {
display: flex;
flex-direction: column;
@@ -3307,9 +3320,8 @@
color: #065f46;
}
.badge-high-protection {
background: #ddd6fe;
color: #5b21b6;
.badge-not-protected {
background: v.$b-color-2;
}
}
@@ -3387,6 +3399,14 @@
overflow-y: auto;
background: v.$white;
&-wrapper {
display: grid;
grid-template-columns: 1fr 300px;
gap: 20px;
height: 100%;
max-height: 80vh;
}
.image-section {
display: flex;
align-items: center;
+34 -2
View File
@@ -5,12 +5,16 @@ import { searchUserFiles, searchGlobalFiles } from '@/app/actions/fileEntity';
export function FileSearchPanel({ fileId, ref }: { fileId: string | null, ref: any }) {
const [searchedUserFiles, setSearchedUserFiles] = useState<string[]>([]);
const [searchedUserFilesShowNull, setSearchedUserFilesShowNull] = useState<boolean>(false);
const [searchedGlobalFiles, setSearchedGlobalFiles] = useState<string[]>([]);
const [searchedGlobalFilesShowNull, setSearchedGlobalFilesShowNull] = useState<boolean>(false);
useImperativeHandle(ref, () => ({
doSomething: () => {
clearList: () => {
setSearchedUserFiles([]);
setSearchedGlobalFiles([])
setSearchedGlobalFiles([]);
setSearchedUserFilesShowNull(false);
setSearchedGlobalFilesShowNull(false);
}
}));
@@ -22,6 +26,8 @@ export function FileSearchPanel({ fileId, ref }: { fileId: string | null, ref: a
if (result.content.length) {
setSearchedUserFiles(result.content);
} else {
setSearchedUserFilesShowNull(true);
}
} catch (error) {
@@ -35,6 +41,8 @@ export function FileSearchPanel({ fileId, ref }: { fileId: string | null, ref: a
let result = await searchGlobalFiles(fileId);
if (result.images.length) {
setSearchedGlobalFiles(result.images);
} else {
setSearchedGlobalFilesShowNull(true);
}
} catch (error) {
@@ -62,7 +70,29 @@ export function FileSearchPanel({ fileId, ref }: { fileId: string | null, ref: a
{(searchedUserFiles.length !== 0) && (
<SearchedUserFilesList list={searchedUserFiles} />
)}
{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>
)}
<div
@@ -141,11 +171,13 @@ export function FileSearchPanel({ fileId, ref }: { fileId: string | null, ref: a
</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>
+16 -14
View File
@@ -3,6 +3,7 @@ import { toast } from 'sonner';
import { useState, ReactNode } from 'react';
import { useTranslations } from 'next-intl';
import ModalWindow from '@/app/components/modalWindow';
import { IconEye, IconDownload } from '@/app/ui/icons/icons';
export function SearchedUserFilesList({ list }: { list: any }) {
const [isFileLoading, setIsFileLoading] = useState(false);
@@ -53,7 +54,7 @@ export function SearchedUserFilesList({ list }: { list: any }) {
<div
className="modal-window-view-file-content"
>
<div className="flex gap-2">
<div className="modal-window-view-file-content-wrapper">
<div className="image-section">
<div className="image-container">
<img
@@ -116,6 +117,7 @@ export function SearchedUserFilesList({ list }: { list: any }) {
className="results-list"
>
{list.map((e: any, index: number) => {
console.log(e);
return (
<div
key={index}
@@ -124,18 +126,20 @@ export function SearchedUserFilesList({ list }: { list: any }) {
<div className="result-item">
<div className="result-header">
<div className="result-preview">
<img src="view-image.php?id=431" alt="Preview" />
{e.url ? (
<img src={e.url} alt="Preview" />
) : (
<div className="preview-fallback">
<span>📄</span>
</div>
)}
</div>
<div className="result-info">
<div className="result-filename" title={e.originalFileName}>
{e.originalFileName}
</div>
<div className="result-details">
Загружен: -
Загружен: {e.uploadDate ? e.uploadDate : '#'}
Размер: {convertBytes(e.fileSize)}
</div>
</div>
@@ -147,31 +151,29 @@ export function SearchedUserFilesList({ list }: { list: any }) {
</div>
<div className="result-badges">
<span className="badge badge-protected">
🛡 Защищено
<span className={`badge ${e.status === 'PROTECTED' ? 'badge-protected' : 'badge-not-protected'}`}>
{e.status}
</span>
<span className="badge badge-high-protection">
🔒 Высокий уровень защиты
</span>
</div>
<div className="result-actions">
<button
className="btn btn-secondary"
className="btn btn-secondary gap-1"
onClick={() => {
handlerViewfile(e);
}}
>
👁 Просмотр
<IconEye />
Просмотр
</button>
<button
className="btn btn-success"
className="btn btn-success gap-1"
disabled={isFileLoading}
onClick={() => handlerDownload(e.fileId, e.originalFileName)}
>
💾 Скачать
<IconDownload />
Скачать
</button>
</div>
</div>
@@ -6,7 +6,7 @@ import { fileUpload, cancelUpload, chunkUpload, checkChunkStatus } from '@/app/a
import { useTranslations } from 'next-intl';
import { useNavigationBlocker } from '@/app/hooks/useNavigationBlocker';
import { useQueryClient } from '@tanstack/react-query';
import { searchUserFiles, removeUserFile, searchGlobalFiles } from '@/app/actions/fileEntity';
import { removeUserFile } from '@/app/actions/fileEntity';
import { FileSearchPanel } from '@/app/ui/search/file-search-panel';
interface SelectedFile {
file: File;
@@ -91,7 +91,7 @@ export default function SectionSearchFile({ fileType, allowedExtensions, maxFile
if (childRef.current) {
//@ts-ignore
childRef.current.doSomething();
childRef.current.clearList();
}
setUploadProgress(0);