import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { QueryObserverSuccessResult, useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
import addStar from '../../api/addStar'
import { ApiError } from '../../api/ApiError'
import getImage from '../../api/getImage'
import getRecipe from '../../api/getRecipe'
import removeStar from '../../api/removeStar'
import GetRecipeView from '../../api/types/GetRecipeView'
import { useAuth } from '../../auth'
import RecipeVisibilityIcon from '../../components/recipe-visibility-icon/RecipeVisibilityIcon'
import UserIconAndName from '../../components/user-icon-and-name/UserIconAndName'
import classes from './recipe.module.css'
import { useNavigate } from '@tanstack/react-router'
interface EditButtonProps {
username: string
slug: string
}
const EditButton = ({ username, slug }: EditButtonProps) => {
const navigate = useNavigate()
return (
)
}
interface RecipeStarInfoProps {
starCount: number
}
const RecipeStarInfo = ({ starCount }: RecipeStarInfoProps) => {
return (
{starCount}
)
}
interface RecipeStarButtonProps {
username: string
slug: string
isStarred: boolean
starCount: number
}
const RecipeStarButton = ({ username, slug, isStarred, starCount }: RecipeStarButtonProps) => {
const authContext = useAuth()
const queryClient = useQueryClient()
const addStarMutation = useMutation({
mutationFn: () => {
if (authContext.token !== null) {
return addStar({
token: authContext.token,
slug,
username
})
} else {
return Promise.resolve()
}
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['recipes', username, slug] })
}
})
const removeStarMutation = useMutation({
mutationFn: () => {
if (authContext.token !== null) {
return removeStar({
token: authContext.token,
slug,
username
})
} else {
return Promise.resolve()
}
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['recipes', username, slug] })
}
})
const onClick = () => {
if (isStarred) {
removeStarMutation.mutate()
} else {
addStarMutation.mutate()
}
}
return (
)
}
export interface RecipeProps {
username: string
slug: string
}
const Recipe = ({ username, slug }: RecipeProps) => {
const authContext = useAuth()
const queryClient = useQueryClient()
const recipeQuery = useQuery(
{
queryKey: ['recipes', username, slug],
queryFn: ({ signal: abortSignal }) =>
getRecipe({
abortSignal,
authContext,
username,
slug
})
},
queryClient
)
const mainImageQuery = useQuery(
{
enabled: recipeQuery.isSuccess,
queryKey: [
'images',
recipeQuery.data?.recipe.mainImage.owner.username,
recipeQuery.data?.recipe.mainImage.filename
],
queryFn: ({ signal }) =>
getImage({
accessToken: authContext.token,
signal,
url: recipeQuery.data!.recipe.mainImage.url
})
},
queryClient
)
if (recipeQuery.isLoading || mainImageQuery.isLoading) {
return 'Loading...'
} else if (recipeQuery.isError) {
const { error } = recipeQuery
if (error instanceof ApiError) {
if (error.status === 404) {
return 'No such recipe.'
} else {
return `ApiError: ${error.status} ${error.message}`
}
} else {
return `Error: ${error.name} ${error.message}`
}
} else if (mainImageQuery.isError) {
const { error } = mainImageQuery
return `Error: ${error.name} ${error.message}`
}
const { data: getRecipeView } = recipeQuery as QueryObserverSuccessResult
const { data: mainImageUrl } = mainImageQuery as QueryObserverSuccessResult
const { recipe, isStarred, isOwner } = getRecipeView
return (
{recipe.title}
{isStarred !== null ? (
) : (
)}
{isOwner ? : null}
)
}
export default Recipe