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