Files
adminpanel/src/pages/SitePromoListPage.jsx
T
2026-06-03 18:38:00 +03:00

118 lines
5.0 KiB
React

import { useState, useRef } from 'react';
import { useNavigate } from 'react-router-dom';
import { useSelector } from 'react-redux';
import { useGetSitePromoListQuery } from '/src/api/apiSitePromo';
import { selectRegions } from '../store/slice/regionSlice';
import { useOutsideClick } from '../hooks/useOutsideClick';
import { LoadingComponent } from '../components/Placeholders/LoadingComponent';
import { ErrorComponent } from '../components/Placeholders/ErrorComponent';
export const SitePromoListPage = () => {
const [ searchValue, setSearchValue ] = useState( '' );
const [ currentPage, setCurrentPage ] = useState( 1 );
const [ expandedId, setExpandedId ] = useState( '' );
const navigate = useNavigate();
const regions = useSelector(selectRegions);
const tableRef = useRef( null );
useOutsideClick( tableRef, () => setExpandedId( null ));
const { data: response = {}, isFetching, error: queryError } =
useGetSitePromoListQuery( { search: searchValue, page: currentPage } );
const pagination = response.pagination || {};
const items = response.data ? response.data : [];
const renderPagination = () => {
const total = pagination.total_pages || 1;
const current = pagination.current_page || 1;
const pages = new Set( [ 1, total ] );
for ( let page = current - 2; page <= current + 2; page += 1 ) {
if ( page > 1 && page < total ) pages.add( page );
}
const sorted = Array.from( pages ).sort( ( a, b ) => a - b );
const elements = [];
let last = 0;
sorted.forEach( page => {
if ( last && page - last > 1 ) {
elements.push(
<li key={ `dots-${last}` } className="page-item disabled">
<span className="page-link"></span>
</li>
);
}
elements.push(
<li key={ page } className={`page-item ${ page === current ? 'active' : '' }`}>
<button type="button" className="page-link" onClick={ () => page !== current && setCurrentPage( page ) }>
{ page }
</button>
</li>
);
last = page;
});
return (
<nav>
<ul className="pagination justify-content-center">
<li className={`page-item ${ !pagination.has_previous_page ? 'disabled' : '' }`}>
<button type="button" className="page-link" onClick={ () => pagination.has_previous_page && setCurrentPage(current - 1) }>&laquo;</button>
</li>
{ elements }
<li className={`page-item ${ !pagination.has_next_page ? 'disabled' : '' }`}>
<button type="button" className="page-link" onClick={ () => pagination.has_next_page && setCurrentPage(current + 1) }>&raquo;</button>
</li>
</ul>
</nav>
);
};
return (
<div className="container-fluid">
<h1 className="h3 mb-4 text-gray-800">Промо (контент)</h1>
<div className="d-flex justify-content-between mb-3" style={{ marginRight: '0.1rem', marginLeft: '0.1rem' }}>
<div className="form-group align-self-end mr-3">
<input type="button" className="btn btn-outline-primary" value="Добавить" onClick={ e => { e.stopPropagation(); navigate(`/site-promo/create`); } } />
</div>
<div className="form-group flex-grow-1">
<label>Поиск</label>
<input type="text" className="form-control" value={ searchValue } onChange={ e => { setSearchValue( e.target.value ); setCurrentPage( 1 ); } } />
</div>
</div>
{ isFetching ? <LoadingComponent /> : queryError ? <ErrorComponent /> : (
<>
<div className="table-responsive" ref={tableRef}>
<table className="table table-hover table-bordered">
<thead><tr>
<th>ID</th>
<th>Название</th>
<th>Alias</th>
<th>Активно</th>
<th>Регион</th>
</tr></thead>
<tbody>
{items.map( item => (
<>
<tr key={ item.id } className={ `cursor-pointer${ expandedId === item.id ? ' table-success' : '' }` } onClick={ () => setExpandedId( expandedId === item.id ? null : item.id ) }>
<td>{ item.id }</td>
<td>{ item.name }</td>
<td>{ item.alias }</td>
<td>{ item.active ? 'Да' : 'Нет' }</td>
<td>{ regions[item.regionId] ?? item.regionId }</td>
</tr>
{ expandedId === item.id && (
<tr className='table-success'>
<td colSpan={ 5 }>
<input type="button" className="btn btn-outline-primary" value="Редактировать" onClick={ e => { e.stopPropagation(); navigate(`/site-promo/edit/${item.id}`) } } />
</td>
</tr>
)}
</>
))}
</tbody>
</table>
</div>
{ renderPagination() }
</>
)}
</div>
);
};