118 lines
5.0 KiB
React
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) }>«</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) }>»</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>
|
|
);
|
|
};
|