add file search and some fixes and bugs

This commit is contained in:
smanylov
2026-01-27 19:52:01 +07:00
parent 1db333a21b
commit 9a6491b76b
14 changed files with 1205 additions and 127 deletions
+6
View File
@@ -145,4 +145,10 @@ export function IconBurgerMenu() {
return (
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" className="icon"><path fill="currentColor" d="M4 6a1 1 0 0 1 1-1h14a1 1 0 1 1 0 2H5a1 1 0 0 1-1-1m0 6a1 1 0 0 1 1-1h14a1 1 0 1 1 0 2H5a1 1 0 0 1-1-1m1 5a1 1 0 1 0 0 2h14a1 1 0 1 0 0-2z" /></svg>
)
}
export function IconSearch() {
return (
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" className="icon"><path fill="currentColor" d="M15.5 14h-.79l-.28-.27A6.47 6.47 0 0 0 16 9.5A6.5 6.5 0 1 0 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5S14 7.01 14 9.5S11.99 14 9.5 14" /></svg>
)
}
@@ -0,0 +1,37 @@
export function SearchedGlobalFilesList({ list }: { list: any }) {
return (
<>
{list.map((item: any, index: number) => {
return (
<div
className="global-result-item"
key={index}
>
<div className="global-result-image">
<img src={item.url} alt={item.pageTitle} />
</div>
<div className="global-result-info">
<div className="global-result-title">
{item.pageTitle}
</div>
<div className="global-result-meta">
<div className="global-result-size">
{item.height}x{item.width}
</div>
<div className="global-result-host">
{item.host}
</div>
</div>
<div className="global-result-passage">
{item.pageTitle}
</div>
<a href={item.pageUrl} target="_blank" className="global-result-url" title={item.pageUrl}>
{item.pageUrl}
</a>
</div>
</div>
)
})}
</>
)
}
@@ -0,0 +1,184 @@
import { convertBytes } from '@/app/lib/convertBytes';
import { toast } from 'sonner';
import { useState, ReactNode } from 'react';
import { useTranslations } from 'next-intl';
import ModalWindow from '@/app/components/modalWindow';
export function SearchedUserFilesList({ list }: { list: any }) {
const [isFileLoading, setIsFileLoading] = useState(false);
const [openWindow, setOpenWindow] = useState<boolean>(false);
const [openWindowChildren, setOpenWindowChildren] = useState<ReactNode>(null);
const t = useTranslations('Global');
const handlerDownload = async (fileId: string, fileName: string) => {
setIsFileLoading(true);
try {
const response = await fetch(`/api/download/${fileId}`);
if (!response.ok) {
throw new Error(`error: ${response.status}`);
}
const blob = await response.blob();
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = fileName || `file-${fileId}`;
document.body.appendChild(a);
a.click();
window.URL.revokeObjectURL(url);
document.body.removeChild(a);
toast.success(`${t('file-is-downloading')} - ${fileName}`);
} catch (error) {
toast.error(t('failed-to-download-file'))
} finally {
setIsFileLoading(false);
}
};
const handlerViewfile = async (e: any) => {
setOpenWindowChildren(() => {
return (
<div
className="modal-window-view-file"
>
<div className="modal-window-view-file-header">
<div
className="modal-window-view-file-title"
>
{e.originalFileName}
</div>
</div>
<div
className="modal-window-view-file-content"
>
<div className="flex gap-2">
<div>
<img
src={e.url ? e.url : '#'}
alt="img"
/>
</div>
<div
className="file-info-card"
>
<div className="info-header">
<h4>Информация о файле</h4>
</div>
<div className="info-item">
<span className="info-label">ID в системе:</span>
<span className="info-value">
{e.supportId ? e.supportId : '#'}
</span>
</div>
<div className="info-item">
<span className="info-label">Дата загрузки:</span>
<span className="info-value">
{e.uploadDate ? e.uploadDate : '#'}
</span>
</div>
<div className="info-item">
<span className="info-label">Размер файла:</span>
<span className="info-value">
{convertBytes(e.fileSize)}
</span>
</div>
<div className="info-item">
<span className="info-label">Статус защиты:</span>
<span className="info-value">
{e.status ? e.status : '#'}
</span>
</div>
</div>
</div>
</div>
</div>
)
})
setOpenWindow(true);
};
return (
<>
<div
className="user-file-search-results"
>
<div className="results-header">
<div className="results-title">Результаты поиска</div>
<div className="results-count">
Найдено файлов: {list.length}
</div>
</div>
<div
className="results-list"
>
{list.map((e: any, index: number) => {
return (
<div
key={index}
>
<div className="result-item">
<div className="result-header">
<div className="result-preview">
<img src="view-image.php?id=431" 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">
Загружен: -
Размер: {convertBytes(e.fileSize)}
</div>
</div>
<div className="similarity-score">
<div className="similarity-percentage">
{e.similarityLevel}
</div>
</div>
</div>
<div className="result-badges">
<span className="badge badge-protected">
🛡 Защищено
</span>
<span className="badge badge-high-protection">
🔒 Высокий уровень защиты
</span>
</div>
<div className="result-actions">
<button
className="btn btn-secondary"
onClick={() => {
handlerViewfile(e);
}}
>
👁 Просмотр
</button>
<button
className="btn btn-success"
disabled={isFileLoading}
onClick={() => handlerDownload(e.fileId, e.originalFileName)}
>
💾 Скачать
</button>
</div>
</div>
</div>)
})}
</div>
</div>
<ModalWindow children={openWindowChildren} state={openWindow} callBack={setOpenWindow} />
</>
)
}