import Input from '@/components/elements/Input';
import InputSpinner from '@/components/elements/InputSpinner';
import { debounce } from 'debounce';
import React, { useCallback, useState } from 'react';
import { TableCheckbox } from '@/components/admin/AdminCheckbox';
import Spinner from '@/components/elements/Spinner';
import styled from 'styled-components/macro';
import tw from 'twin.macro';
import { PaginatedResult, PaginationDataSet } from '@/api/http';
export const TableHeader = ({ name, onClick, direction }: { name?: string, onClick?: (e: React.MouseEvent) => void, direction?: number | null }) => {
if (!name) {
return
| ;
}
return (
{name}
{direction !== undefined ?
:
null
}
|
);
};
export const TableHead = ({ children }: { children: React.ReactNode }) => {
return (
{children}
);
};
export const TableBody = ({ children }: { children: React.ReactNode }) => {
return (
{children}
);
};
export const TableRow = ({ children }: { children: React.ReactNode }) => {
return (
{children}
);
};
interface Props {
data?: PaginatedResult;
onPageSelect: (page: number) => void;
children: React.ReactNode;
}
const PaginationButton = styled.button<{ active?: boolean }>`
${tw`relative items-center px-3 py-1 -ml-px text-sm font-normal leading-5 transition duration-150 ease-in-out border border-neutral-500 focus:z-10 focus:outline-none focus:border-primary-300 inline-flex`};
${props => props.active ? tw`bg-neutral-500 text-neutral-50` : tw`bg-neutral-600 text-neutral-200 hover:text-neutral-50`};
`;
const PaginationArrow = styled.button`
${tw`relative inline-flex items-center px-1 py-1 text-sm font-medium leading-5 transition duration-150 ease-in-out border border-neutral-500 bg-neutral-600 text-neutral-400 hover:text-neutral-50 focus:z-10 focus:outline-none focus:border-primary-300`};
&:disabled {
${tw`bg-neutral-700`}
}
&:hover:disabled {
${tw`text-neutral-400 cursor-default`};
}
`;
export function Pagination ({ data, onPageSelect, children }: Props) {
let pagination: PaginationDataSet;
if (data === undefined) {
pagination = {
total: 0,
count: 0,
perPage: 0,
currentPage: 1,
totalPages: 1,
};
} else {
pagination = data.pagination;
}
const setPage = (page: number) => {
if (page < 1 || page > pagination.totalPages) {
return;
}
onPageSelect(page);
};
const isFirstPage = pagination.currentPage === 1;
const isLastPage = pagination.currentPage >= pagination.totalPages;
const pages = [];
if (pagination.totalPages < 7) {
for (let i = 1; i <= pagination.totalPages; i++) {
pages.push(i);
}
} else {
// Don't ask me how this works, all I know is that this code will always have 7 items in the pagination,
// and keeps the current page centered if it is not too close to the start or end.
let start = Math.max(pagination.currentPage - 3, 1);
const end = Math.min(pagination.totalPages, pagination.currentPage + ((pagination.currentPage < 4) ? 7 - pagination.currentPage : 3));
while (start !== 1 && end - start !== 6) {
start--;
}
for (let i = start; i <= end; i++) {
pages.push(i);
}
}
return (
<>
{children}
Showing {((pagination.currentPage - 1) * pagination.perPage) + 1} to {((pagination.currentPage - 1) * pagination.perPage) + pagination.count} of {pagination.total} results
{isFirstPage && isLastPage ?
null
:
}
>
);
}
export const Loading = () => {
return (
);
};
export const NoItems = () => {
return (
No items could be found, it's almost like they are hiding.
);
};
interface Params {
checked: boolean;
onSelectAllClick: (e: React.ChangeEvent) => void;
onSearch?: (query: string) => Promise;
children: React.ReactNode;
}
export const ContentWrapper = ({ checked, onSelectAllClick, onSearch, children }: Params) => {
const [ loading, setLoading ] = useState(false);
const [ inputText, setInputText ] = useState('');
const search = useCallback(
debounce((query: string) => {
if (onSearch === undefined) {
return;
}
setLoading(true);
onSearch(query).then(() => setLoading(false));
}, 200),
[],
);
return (
<>
{children}
>
);
};
export default ({ children }: { children: React.ReactNode }) => {
return (
);
};