meals-made-easy-app/src/pages/recipes/Recipes.tsx
2024-08-08 10:44:11 -05:00

98 lines
3.4 KiB
TypeScript

import { useQueries, useQuery, useQueryClient } from '@tanstack/react-query'
import { useState } from 'react'
import { ApiError } from '../../api/ApiError'
import getImage from '../../api/getImage'
import getRecipeInfos from '../../api/getRecipeInfos'
import { useAuth } from '../../auth'
import RecipeCard from '../../components/recipe-card/RecipeCard'
import classes from './recipes.module.css'
const Recipes = () => {
const [pageNumber, setPageNumber] = useState(0)
const [pageSize, setPageSize] = useState(20)
const { token } = useAuth()
const queryClient = useQueryClient()
const { data, isPending, error } = useQuery(
{
queryKey: ['recipeInfos'],
queryFn: ({ signal }) =>
getRecipeInfos({
abortSignal: signal,
pageNumber,
pageSize,
token
})
},
queryClient
)
const slugsAndImgUrls = useQueries({
queries:
data !== undefined
? data.content.map(recipeInfoView => {
return {
queryKey: [
'images',
recipeInfoView.mainImage.owner.username,
recipeInfoView.mainImage.filename
],
queryFn: async ({ signal }: any) => {
// any needed in the params
const imgUrl = await getImage({
accessToken: token,
signal,
url: recipeInfoView.mainImage.url
})
return {
slug: recipeInfoView.slug,
imgUrl
}
}
}
})
: []
})
if (isPending) {
return <p>Loading...</p>
} else if (error) {
if (error instanceof ApiError) {
return (
<p>
ApiError: {error.status} {error.message}
</p>
)
} else {
return <p>Error: {error.message}</p>
}
} else {
return (
<>
<h1>Recipes</h1>
<section className={classes.recipeList}>
{data.content.map(view => (
<RecipeCard
key={view.id}
title={view.title}
ownerUsername={view.ownerUsername}
slug={view.slug}
mainImageUrl={
slugsAndImgUrls.find(({ data: slugAndImgUrl }) => {
return slugAndImgUrl !== undefined && slugAndImgUrl.slug === view.slug
})?.data!.imgUrl ?? '' // hacky workaround. should pass a kind of <Image> child which loads its own data
}
mainImageAlt={view.mainImage.alt ? view.mainImage.alt : undefined}
starCount={view.starCount}
isPublic={view.isPublic}
/>
))}
</section>
</>
)
}
}
export default Recipes