Skip to main content
Glama

Storyden

by Southclaws
Mozilla Public License 2.0
229
PaginationControls.tsx3.13 kB
import { range } from "lodash"; import { parseAsInteger, useQueryState } from "nuqs"; import { MouseEvent, useState } from "react"; import { LinkButton } from "@/components/ui/link-button"; import { HStack, styled } from "@/styled-system/jsx"; const MAX_PAGES_SHOWN = 5; const MID_POINT = MAX_PAGES_SHOWN / 2; export type Props = { path: string; params?: Record<string, string>; currentPage: number; totalPages: number; pageSize: number; onClick?: (page: number) => void; }; export function PaginationControls({ path, params, currentPage, totalPages, onClick, }: Props) { if (totalPages <= 1) { return null; } // NOTE: pages are 1-indexed const lastPage = totalPages; const lastPageIndex = totalPages + 1; const allPages = range(1, lastPageIndex); const tooMany = allPages.length > MAX_PAGES_SHOWN; const nearEnd = lastPage - currentPage < MID_POINT; const nearStart = currentPage < MID_POINT; const needStartJump = tooMany && currentPage > MID_POINT + 1; const needEndJump = tooMany && currentPage < lastPage - MID_POINT; const getPages = () => { if (!tooMany) { return allPages; } if (nearEnd) { return range(lastPageIndex - MAX_PAGES_SHOWN, lastPageIndex); } if (nearStart) { return range(1, MAX_PAGES_SHOWN + 1); } const start = currentPage - 3; const end = currentPage + 2; return allPages.slice(start, end); }; const targetPages = getPages(); const clickHandler = (page: number) => (event: MouseEvent<HTMLAnchorElement>) => { if (onClick) { event.preventDefault(); onClick(page); } }; return ( <HStack w="min" p="1"> {needStartJump && ( <> <LinkButton variant="ghost" size="xs" href={`${path}?${new URLSearchParams({ ...params, page: "1", }).toString()}`} onClick={clickHandler(1)} > {1} </LinkButton> <Sep /> </> )} {targetPages.map((v) => { const pageName = v.toString(); const withPage = new URLSearchParams({ ...params, page: pageName, }); return ( <LinkButton variant="ghost" backgroundColor={v === currentPage ? "bg.muted" : undefined} size="xs" key={v} href={`${path}?${withPage.toString()}`} onClick={clickHandler(v)} > {pageName} </LinkButton> ); })} {needEndJump && ( <> <Sep /> <LinkButton variant="ghost" size="xs" href={`${path}?${new URLSearchParams({ ...params, page: lastPage.toString(), }).toString()}`} onClick={clickHandler(lastPage)} > {lastPage} </LinkButton> </> )} </HStack> ); } function Sep() { return ( <styled.span fontSize="xs" color="fg.disabled"> ••• </styled.span> ); }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Southclaws/storyden'

If you have feedback or need assistance with the MCP directory API, please join our Discord server