mirror of
https://github.com/maciejpedzich/cats-album.git
synced 2024-11-27 22:35:47 +01:00
Create a page for displaying cats in page chunks
This commit is contained in:
parent
8592ebc8f2
commit
d36de6ccbd
66
src/components/CatCard.astro
Normal file
66
src/components/CatCard.astro
Normal 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
80
src/pages/[...page].astro
Normal 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>
|
@ -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>
|
|
Loading…
Reference in New Issue
Block a user