feat: implement barebone zola templates

This commit is contained in:
Alexander Navarro 2024-11-10 21:45:59 +00:00
parent 9c20f5ed2e
commit f99a9ae2ac
198 changed files with 2434 additions and 227991 deletions

View file

@ -1,124 +0,0 @@
import { useReducer } from 'react';
interface Page {
page: number;
current: boolean;
}
interface IUsePagination<T> {
items: T[];
changeOffset: (offset: Offset, newValue?: number) => void;
/**
* Returns an array with the aviables pages to directly navigate.
* This pages are centered in the current page and offest to 5 items to each side.
* @returns {Page}
*/
getPaginationRange: () => Page[];
}
interface Props<T> {
items: T[];
limit: number;
}
interface State {
offset: number;
total: number;
limit: number;
}
type ActionType =
| { type: 'update'; value: any; name: string }
| { type: 'update'; value: any; name: string };
export enum Offset {
Next,
Prev,
First,
Last,
To,
}
export default function usePagination<T>({
items,
limit = 30,
}: Props<T>): IUsePagination<T> {
const reducer = (state: State, action: ActionType): State => {
switch (action.type) {
case 'update':
return {
...state,
[action.name]: action.value,
};
default:
return state;
}
};
const [state, dispatch] = useReducer(reducer, {
offset: 0,
total: 0,
limit,
});
const changeOffset = (offset: Offset, newValue: number = 1): void => {
let value = 0;
switch (offset) {
case Offset.Next:
value = state.offset + state.limit;
break;
case Offset.Prev:
value = state.offset - state.limit;
break;
case Offset.First:
value = 0;
break;
case Offset.Last:
value = items.length - state.limit;
break;
case Offset.To:
value = (newValue - 1) * state.limit;
break;
default:
break;
}
if (value < 0 || value > items.length - state.limit) {
return;
}
dispatch({
type: 'update',
name: 'offset',
value,
});
};
function getPaginationRange(): Page[] {
// NOTE: this is made to work with uneven numbers,
// So the current page is always aligned in the center.
const paginationToSides = 5;
const currentPage = Math.ceil(state.offset / state.limit) + 1;
const lastPage = Math.ceil(items.length / state.limit);
const start = Math.max(currentPage - paginationToSides - 1, 0);
const end = Math.min(currentPage + paginationToSides, lastPage);
return Array.from(
{
length: end - start,
},
(_, idx) => {
const page = idx + 1 + start;
return { page, current: page === currentPage };
},
);
}
return {
changeOffset,
getPaginationRange,
items: items.slice(state.offset, state.offset + state.limit),
};
}