Create a page for displaying cats in page chunks

This commit is contained in:
Maciej Pędzich 2023-09-02 20:51:00 +02:00
parent 8592ebc8f2
commit d36de6ccbd
3 changed files with 146 additions and 15 deletions

View File

@ -0,0 +1,66 @@
---
import { type CollectionEntry } from 'astro:content';
export interface Props {
cat: CollectionEntry<'cats'>;
}
const { cat } = Astro.props;
---
<a class="card-link-wrapper" href={`/cats/${cat.id}`}>
<div class="card is-center">
<h4>{cat.data.name}</h4>
<p>{cat.data.owner.name}</p>
<div class="img-wrapper">
<img
src={cat.data.image.src}
alt={cat.data.image.alt}
loading="lazy"
decoding="async"
/>
</div>
</div>
</a>
<style>
.card-link-wrapper {
color: var(--font-color);
}
.card-link-wrapper:hover {
opacity: 1;
}
.card-link-wrapper:focus {
outline: var(--color-primary) solid 5px;
}
.card {
margin: 0.5rem 0;
padding: 0;
flex-direction: column;
}
.card h4 {
margin: 1.25rem 0 0.25rem 0;
}
.img-wrapper {
position: relative;
overflow: hidden;
}
.card img {
display: block;
width: 100%;
max-height: 300px;
object-fit: cover;
transition: transform;
transition-duration: 300ms;
}
.card:hover img {
transform: scale(1.1);
}
</style>

80
src/pages/[...page].astro Normal file
View File

@ -0,0 +1,80 @@
---
import { getCollection, type CollectionEntry } from 'astro:content';
import BaseLayout from '../layouts/BaseLayout.astro';
import CatCard from '../components/CatCard.astro';
export interface Props {
cats: CollectionEntry<'cats'>[];
pageNums: number[];
}
export async function getStaticPaths() {
const NUM_CATS_PER_PAGE = 18;
const [firstCat] = await getCollection('cats');
const allCats = Array(100).fill(firstCat);
const maxPageNum = Math.ceil(allCats.length / NUM_CATS_PER_PAGE);
const pageNums = [...Array(maxPageNum).keys()].map((key) => key + 1);
return pageNums.map((num) => ({
params: { page: num === 1 ? undefined : num.toString() },
props: {
cats: allCats.slice(
NUM_CATS_PER_PAGE * (num - 1),
NUM_CATS_PER_PAGE * num
),
pageNums
}
}));
}
const { page } = Astro.params;
const { cats, pageNums } = Astro.props;
const currentPageNum = Number(page || '1');
---
<BaseLayout title={page ? `Page ${page}` : undefined}>
<div class="row">
{
cats.map((cat) => (
<div class="col-12 col-6-md col-4-lg">
<CatCard cat={cat} />
</div>
))
}
</div>
<nav class="nav" aria-label="Page navigation">
<div class="nav-center">
{
pageNums.map((num) => (
<a
href={`/${num === 1 ? '' : num.toString()}`}
class:list={[{ active: num === currentPageNum }]}
>
{num}
</a>
))
}
</div>
</nav>
</BaseLayout>
<style>
.nav {
margin-top: 1rem;
}
.nav a {
font-size: 2rem;
}
.nav a.active {
font-weight: bold;
}
.nav a:hover {
text-decoration: underline;
}
</style>

View File

@ -1,15 +0,0 @@
---
---
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="viewport" content="width=device-width" />
<meta name="generator" content={Astro.generator} />
<title>Astro</title>
</head>
<body>
<h1>Astro</h1>
</body>
</html>