Added zod. Wrapped picsum API.
This commit is contained in:
parent
2137fcc776
commit
ae6451e052
3 changed files with 78 additions and 11 deletions
82
src/App.tsx
82
src/App.tsx
|
|
@ -1,12 +1,78 @@
|
|||
import { CssBaseline, Typography } from '@mui/material';
|
||||
import { z } from 'zod'
|
||||
// TODO: Use Material UI later.
|
||||
// TODO: Improve error-handling. Introduce some proper server response.
|
||||
|
||||
type ImageId = string
|
||||
type ImageRef = string
|
||||
|
||||
type Image = {
|
||||
id: ImageId,
|
||||
dimension: Dimension,
|
||||
source: ImageRef,
|
||||
}
|
||||
|
||||
type Dimension = {
|
||||
width: number,
|
||||
height: number,
|
||||
}
|
||||
|
||||
// WARNING: page starts at 1
|
||||
type Pagination = {
|
||||
page: number,
|
||||
limit: number, // page size
|
||||
}
|
||||
|
||||
const Pagination = {
|
||||
init(): Pagination { return { page: 1, limit: 10 } },
|
||||
}
|
||||
|
||||
|
||||
// === api ===
|
||||
const picsumApiImageSchema = z.object({
|
||||
id: z.string(),
|
||||
author: z.string(),
|
||||
width: z.number(),
|
||||
height: z.number(),
|
||||
url: z.string(),
|
||||
download_url: z.string(), // WARNING: the api-endpoint returns "url" and "download_url". You definitely want "download_url" for image sources.
|
||||
})
|
||||
type PicsumApiImage = z.infer<typeof picsumApiImageSchema>
|
||||
|
||||
async function getPicsumImages({ page, limit }: Pagination): Promise<PicsumApiImage[]> {
|
||||
const response = await fetch(`https://picsum.photos/v2/list?limit=${limit}&page=${page}`)
|
||||
if (!response.ok) {
|
||||
throw new Error(`Failed to fetch images: ${response.status}`)
|
||||
}
|
||||
|
||||
const json: unknown = await response.json()
|
||||
const data = z.array(picsumApiImageSchema).parse(json)
|
||||
|
||||
return data
|
||||
}
|
||||
|
||||
async function getImages(pagination: Pagination): Promise<Image[]> {
|
||||
const data = await getPicsumImages(pagination)
|
||||
return data.map(({ id, download_url, width, height }) => ({ id: id as ImageId, dimension: { width, height }, source: download_url as ImageRef }))
|
||||
}
|
||||
|
||||
async function getImageIds(pagination: Pagination): Promise<ImageId[]> {
|
||||
const data = await getPicsumImages(pagination)
|
||||
return data.map(({ id }) => id)
|
||||
}
|
||||
|
||||
// Use this for `<img src=... />`
|
||||
function getImageSource(id: ImageId, dimension: Dimension): ImageRef {
|
||||
return `https://picsum.photos/id/${id}/${dimension.width}/${dimension.height}`;
|
||||
}
|
||||
|
||||
// test
|
||||
// (async () => {
|
||||
// const imgs = await getImages({ page: 2, limit: 10 })
|
||||
// console.log(imgs)
|
||||
// })()
|
||||
|
||||
export default function App() {
|
||||
return (
|
||||
<>
|
||||
<CssBaseline />
|
||||
<main>
|
||||
<Typography variant="h1">Hello world</Typography>
|
||||
</main>
|
||||
</>
|
||||
);
|
||||
<h1>hello world</h1>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue