add pagination for test
This commit is contained in:
@@ -28,8 +28,43 @@ export async function searchUserFiles(fileId: string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function searchGlobalFiles(fileId: string) {
|
export async function searchGlobalFiles(fileId: string, currentPage: number) {
|
||||||
const token = await getSessionData('token');
|
const token = await getSessionData('token');
|
||||||
|
console.log('searchGlobalFiles');
|
||||||
|
console.log(currentPage);
|
||||||
|
|
||||||
|
/* return {
|
||||||
|
images: [
|
||||||
|
{
|
||||||
|
url: 'string1',
|
||||||
|
pageTitle: `string1 from page ${currentPage}`,
|
||||||
|
height: 100,
|
||||||
|
width: 100,
|
||||||
|
host: 'string1',
|
||||||
|
pageUrl: 'string1'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
url: 'string1',
|
||||||
|
pageTitle: `string2 from page ${currentPage}`,
|
||||||
|
height: 100,
|
||||||
|
width: 100,
|
||||||
|
host: 'string1',
|
||||||
|
pageUrl: 'string1'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
url: 'string1',
|
||||||
|
pageTitle: `string3 from page ${currentPage}`,
|
||||||
|
height: 100,
|
||||||
|
width: 100,
|
||||||
|
host: 'string1',
|
||||||
|
pageUrl: 'string1'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
page: 0,
|
||||||
|
pageSize: 0,
|
||||||
|
totalPages: 10,
|
||||||
|
totalResults: 100,
|
||||||
|
} */
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await fetch(`${API_BASE_URL}/api/v1/data`, {
|
const response = await fetch(`${API_BASE_URL}/api/v1/data`, {
|
||||||
@@ -77,7 +112,7 @@ export async function getSearchStats() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
let parsed = await response.json();
|
let parsed = await response.json();
|
||||||
|
|||||||
@@ -0,0 +1,67 @@
|
|||||||
|
'use client'
|
||||||
|
|
||||||
|
export function Pagination({ totalPages, currentPage, fileId, callBack }: any) {
|
||||||
|
|
||||||
|
const getVisiblePages = () => {
|
||||||
|
const pages = [];
|
||||||
|
const maxVisible = 7;
|
||||||
|
let start = Math.max(1, currentPage - 3);
|
||||||
|
let end = Math.min(totalPages, currentPage + 3);
|
||||||
|
|
||||||
|
if (end - start + 1 < maxVisible) {
|
||||||
|
if (start === 1) {
|
||||||
|
end = Math.min(totalPages, start + maxVisible - 1);
|
||||||
|
} else if (end === totalPages) {
|
||||||
|
start = Math.max(1, end - maxVisible + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = start; i <= end; i++) {
|
||||||
|
pages.push(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
return pages;
|
||||||
|
};
|
||||||
|
|
||||||
|
const visiblePages = getVisiblePages();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<div style={{ display: 'flex', gap: '5px', marginTop: '10px' }}>
|
||||||
|
{/* Кнопка первой страницы */}
|
||||||
|
{visiblePages[0] > 1 && (
|
||||||
|
<>
|
||||||
|
<button onClick={() => callBack(fileId, 1)}>1</button>
|
||||||
|
{visiblePages[0] > 2 && <span>...</span>}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Видимые страницы */}
|
||||||
|
{visiblePages.map(page => (
|
||||||
|
<button
|
||||||
|
key={page}
|
||||||
|
onClick={() => callBack(fileId, page)}
|
||||||
|
style={{
|
||||||
|
padding: '5px 10px',
|
||||||
|
border: '1px solid #ddd',
|
||||||
|
background: currentPage === page ? '#007bff' : 'white',
|
||||||
|
color: currentPage === page ? 'white' : 'black',
|
||||||
|
cursor: 'pointer',
|
||||||
|
fontWeight: currentPage === page ? 'bold' : 'normal'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{page}
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
|
||||||
|
{/* Кнопка последней страницы */}
|
||||||
|
{visiblePages[visiblePages.length - 1] < totalPages && (
|
||||||
|
<>
|
||||||
|
{visiblePages[visiblePages.length - 1] < totalPages - 1 && <span>...</span>}
|
||||||
|
<button onClick={() => callBack(fileId, totalPages)}>{totalPages}</button>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -3,16 +3,29 @@ import { SearchedGlobalFilesList } from '@/app/ui/search/searched-global-files-l
|
|||||||
import { useCallback, useState, useImperativeHandle } from 'react';
|
import { useCallback, useState, useImperativeHandle } from 'react';
|
||||||
import { searchUserFiles, searchGlobalFiles } from '@/app/actions/searchActions';
|
import { searchUserFiles, searchGlobalFiles } from '@/app/actions/searchActions';
|
||||||
import { useQueryClient } from '@tanstack/react-query';
|
import { useQueryClient } from '@tanstack/react-query';
|
||||||
|
import { Pagination } from '@/app/components/Pagination';
|
||||||
|
|
||||||
|
export interface SearchItem {
|
||||||
|
url: string,
|
||||||
|
pageTitle: string,
|
||||||
|
height: number,
|
||||||
|
width: number,
|
||||||
|
host: string,
|
||||||
|
pageUrl: string
|
||||||
|
}
|
||||||
|
|
||||||
export function FileSearchPanel({ fileId, ref }: { fileId: string | null, ref: any }) {
|
export function FileSearchPanel({ fileId, ref }: { fileId: string | null, ref: any }) {
|
||||||
const [searchedUserFiles, setSearchedUserFiles] = useState<string[]>([]);
|
const [searchedUserFiles, setSearchedUserFiles] = useState<string[]>([]);
|
||||||
const [searchedUserFilesShowNull, setSearchedUserFilesShowNull] = useState<boolean>(false);
|
const [searchedUserFilesShowNull, setSearchedUserFilesShowNull] = useState<boolean>(false);
|
||||||
const [searchedGlobalFiles, setSearchedGlobalFiles] = useState<string[]>([]);
|
const [searchedGlobalFiles, setSearchedGlobalFiles] = useState<SearchItem[]>([]);
|
||||||
const [searchedGlobalFilesShowNull, setSearchedGlobalFilesShowNull] = useState<boolean>(false);
|
const [searchedGlobalFilesShowNull, setSearchedGlobalFilesShowNull] = useState<boolean>(false);
|
||||||
const [loading, setLoading] = useState<boolean>(false);
|
const [loading, setLoading] = useState<boolean>(false);
|
||||||
const [showGlobalSearch, setShowGlobalSearch] = useState<boolean>(false);
|
const [showGlobalSearch, setShowGlobalSearch] = useState<boolean>(false);
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
|
|
||||||
|
const [searchTotalPages, setSearchTotalPages] = useState<number>(0);
|
||||||
|
const [searchCurrentPages, setSearchCurrentPages] = useState<number>(1);
|
||||||
|
|
||||||
useImperativeHandle(ref, () => ({
|
useImperativeHandle(ref, () => ({
|
||||||
clearList: () => {
|
clearList: () => {
|
||||||
setSearchedUserFiles([]);
|
setSearchedUserFiles([]);
|
||||||
@@ -24,7 +37,7 @@ export function FileSearchPanel({ fileId, ref }: { fileId: string | null, ref: a
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
|
|
||||||
const handlerSearchUserFile = useCallback(async (fileId: string): Promise<void> => {
|
const handlerSearchUserFile = useCallback(async (fileId: string, page: number): Promise<void> => {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let result = await searchUserFiles(fileId);
|
let result = await searchUserFiles(fileId);
|
||||||
@@ -38,21 +51,25 @@ export function FileSearchPanel({ fileId, ref }: { fileId: string | null, ref: a
|
|||||||
|
|
||||||
}
|
}
|
||||||
setShowGlobalSearch(true);
|
setShowGlobalSearch(true);
|
||||||
handlerSearchGlobalFile(fileId)
|
handlerSearchGlobalFile(fileId, page)
|
||||||
|
|
||||||
}, [fileId])
|
}, [fileId])
|
||||||
|
|
||||||
const handlerSearchGlobalFile = useCallback(async (fileId: string): Promise<void> => {
|
const handlerSearchGlobalFile = useCallback(async (fileId: string, page: number): Promise<void> => {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
setSearchedGlobalFilesShowNull(false);
|
setSearchedGlobalFilesShowNull(false);
|
||||||
setSearchedGlobalFiles([]);
|
setSearchedGlobalFiles([]);
|
||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let result = await searchGlobalFiles(fileId);
|
let result = await searchGlobalFiles(fileId, page);
|
||||||
|
console.log('searchGlobalFiles');
|
||||||
console.log(result);
|
console.log(result);
|
||||||
if (result.images.length) {
|
if (result.images.length) {
|
||||||
setSearchedGlobalFiles(result.images);
|
setSearchedGlobalFiles(result.images);
|
||||||
|
setSearchTotalPages(result.totalPages);
|
||||||
|
setSearchCurrentPages(page);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
setSearchedGlobalFilesShowNull(true);
|
setSearchedGlobalFilesShowNull(true);
|
||||||
}
|
}
|
||||||
@@ -76,7 +93,7 @@ export function FileSearchPanel({ fileId, ref }: { fileId: string | null, ref: a
|
|||||||
disabled={fileId ? false : true}
|
disabled={fileId ? false : true}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (fileId) {
|
if (fileId) {
|
||||||
handlerSearchUserFile(fileId)
|
handlerSearchUserFile(fileId, 1)
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
@@ -187,6 +204,8 @@ export function FileSearchPanel({ fileId, ref }: { fileId: string | null, ref: a
|
|||||||
<strong>Ошибка глобального поиска:</strong>
|
<strong>Ошибка глобального поиска:</strong>
|
||||||
<span id="global-error-text"></span>
|
<span id="global-error-text"></span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<Pagination totalPages={searchTotalPages} currentPage={searchCurrentPages} fileId={fileId} callBack={handlerSearchGlobalFile}/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -17,10 +17,6 @@ export function SearchStats() {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
console.log(userSearchData);
|
|
||||||
}, [userSearchData]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="stats-search">
|
<div className="stats-search">
|
||||||
<div className="stats-title">
|
<div className="stats-title">
|
||||||
|
|||||||
@@ -1,37 +1,43 @@
|
|||||||
export function SearchedGlobalFilesList({ list }: { list: any }) {
|
import { SearchItem } from './file-search-panel'
|
||||||
|
|
||||||
|
export function SearchedGlobalFilesList({ list }: { list: SearchItem[] }) {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{list.map((item: any, index: number) => {
|
{list.map(
|
||||||
return (
|
(
|
||||||
<div
|
item: SearchItem, index: number
|
||||||
className="global-result-item"
|
) => {
|
||||||
key={index}
|
return (
|
||||||
>
|
<div
|
||||||
<div className="global-result-image">
|
className="global-result-item"
|
||||||
<img src={item.url} alt={item.pageTitle} />
|
key={index}
|
||||||
</div>
|
>
|
||||||
<div className="global-result-info">
|
<div className="global-result-image">
|
||||||
<div className="global-result-title">
|
<img src={item?.url} alt={item?.pageTitle} />
|
||||||
{item.pageTitle}
|
|
||||||
</div>
|
</div>
|
||||||
<div className="global-result-meta">
|
<div className="global-result-info">
|
||||||
<div className="global-result-size">
|
<div className="global-result-title">
|
||||||
{item.height}x{item.width}
|
{item?.pageTitle}
|
||||||
</div>
|
</div>
|
||||||
<div className="global-result-host">
|
<div className="global-result-meta">
|
||||||
{item.host}
|
<div className="global-result-size">
|
||||||
|
{item?.height}x{item?.width}
|
||||||
|
</div>
|
||||||
|
<div className="global-result-host">
|
||||||
|
{item?.host}
|
||||||
|
</div>
|
||||||
</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>
|
||||||
<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>
|
||||||
</div>
|
)
|
||||||
)
|
})}
|
||||||
})}
|
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user