0.1.5Updated 6 months ago
import { PrettyNumber } from "@islands/utils/pretty_number.ts";
import type { I_Pagination } from "@infinity-beyond/modules/pagination.ts";

import { ChevronLeft, ChevronRight, type LucideIcon } from "lucide-preact";

type I_PaginationOptions = {
  meta: I_Pagination
  entry_plural?: string
}

export function Pagination({  meta: { page, total_pages, page_size, current_item_count, total_items }, entry_plural = "entries" }: I_PaginationOptions) {
  const count_start = page_size * (page - 1);

  console.log('total_pages', total_pages);
  console.log('total_items', total_items);
  console.log('current_item_count', current_item_count);
  console.log('page_size', page_size);

  // deno-lint-ignore jsx-no-useless-fragment
  if(total_pages == 1) return <></>;

  let pagination_start = Math.max(1, page - 2);
  let pagination_end = Math.min(total_pages, page + 2);

  if(pagination_start < 3) pagination_end = Math.min(total_pages, 7);
  if(pagination_start !== 1 && pagination_end > total_pages - 3) pagination_start = Math.max(1, total_pages - 6);

  const pages_to_render = new Array(pagination_end - pagination_start + 1).fill(0).map((_, i) => pagination_start + i);

  return <div class='flex items-center py-12 flex-col'>
    <div class="flex gap-2">
      <PaginationButton page={page - 1} disabled={page==1} icon={ChevronLeft} />
      <div class="join">
        { pagination_start > 1 && <>
          <PaginationButton page={1} />
          { pagination_start > 2 && 
            <PaginationSpacer />
          }
        </>}
        { pages_to_render.map(page_index =>
          <PaginationButton page_size={page_size} page={page_index} key={page_index} active={page == page_index} />
        )}
        {/* <PaginationButton page_size={page_size} page={page - 1} />
        <PaginationButton page_size={page_size} page={page} active />
        <PaginationButton page_size={page_size} page={page + 1} />
        <PaginationButton page_size={page_size} page={page + 2} /> */}
        { pagination_end < total_pages && <>
          { pagination_end < total_pages - 1 && 
            <PaginationSpacer />
          }
          <PaginationButton page={total_pages} />
        </>}
      </div>
      <PaginationButton page={page + 1} disabled={page == total_pages} icon={ChevronRight} />
    </div>
    <div class="pt-4">
      Showing { entry_plural } { PrettyNumber(count_start + 1) } - { PrettyNumber(count_start + current_item_count) } of { PrettyNumber(total_items) }
    </div>
  </div>
}

interface I_PaginationButton {
  page: number
  page_size?: number
  active?: boolean
  text?: string
  icon?: LucideIcon
  disabled?: boolean
}

function PaginationButton(params: I_PaginationButton) {
  const { page, active, text, page_size, disabled } = params;

  return <a
      class={"join-item btn" + (active ? ' btn-active' : '')}
      href={`?page=${page}${page_size ? `&page_size=${page_size}` : ''}`}
      disabled={disabled}
    >{
      params.icon ?
        // @ts-expect-error Lucide-Preact type issue - Working
      <params.icon />
      :
        text || page
      }
    </a>
}

function PaginationSpacer() {
  return <a class="join-item btn" disabled>...</a>
}