Recipe page star different when logged in or not. Styling of recipe star.

This commit is contained in:
Jesse Brault 2024-08-14 18:17:40 -05:00
parent 4d383c6fc8
commit 34b57e0ccc
3 changed files with 119 additions and 50 deletions

View File

@ -4,6 +4,12 @@
--primary-white: #ffffff; --primary-white: #ffffff;
--primary-red: #91351d; --primary-red: #91351d;
--primary-yellow: #ffb61d; --primary-yellow: #ffb61d;
--primary-black: #252525;
--off-white-1: #eee;
--off-white-2: #ddd;
--off-white-3: #ccc;
--off-white-4: #bbb;
--off-white-5: #aaa;
} }
body { body {

View File

@ -11,6 +11,81 @@ import classes from './recipe.module.css'
import addStar from '../../api/addStar' import addStar from '../../api/addStar'
import removeStar from '../../api/removeStar' import removeStar from '../../api/removeStar'
interface RecipeStarInfoProps {
starCount: number
}
const RecipeStarInfo = ({ starCount }: RecipeStarInfoProps) => {
return (
<div className={classes.starContainer}>
<FontAwesomeIcon icon="star" className={classes.star} size="sm" />
<span className={classes.starCount}>{starCount}</span>
</div>
)
}
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 (
<button className={classes.starContainer} onClick={onClick}>
<FontAwesomeIcon icon="star" className={classes.star} size="sm" />
<span className={classes.starred}>{isStarred ? 'Starred' : 'Star'}</span>
<span className={classes.starCount}>{starCount}</span>
</button>
)
}
export interface RecipeProps { export interface RecipeProps {
username: string username: string
slug: string slug: string
@ -48,50 +123,6 @@ const Recipe = ({ username, slug }: RecipeProps) => {
queryClient queryClient
) )
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 onStarButtonClick = () => {
if (recipeQuery.isSuccess) {
if (recipeQuery.data.isStarred) {
removeStarMutation.mutate()
} else {
addStarMutation.mutate()
}
}
}
if (recipeQuery.isLoading || mainImageQuery.isLoading) { if (recipeQuery.isLoading || mainImageQuery.isLoading) {
return 'Loading...' return 'Loading...'
} else if (recipeQuery.isError) { } else if (recipeQuery.isError) {
@ -119,11 +150,15 @@ const Recipe = ({ username, slug }: RecipeProps) => {
<div className={classes.info}> <div className={classes.info}>
<div className={classes.infoRow}> <div className={classes.infoRow}>
<h1 className={classes.recipeTitle}>{recipe.title}</h1> <h1 className={classes.recipeTitle}>{recipe.title}</h1>
<button className={classes.starButton} onClick={onStarButtonClick}> {recipe.isStarred !== null ? (
<FontAwesomeIcon icon="star" className={classes.star} size="sm" /> <RecipeStarButton
<span>{recipe.isStarred ? 'Starred' : 'Star'}</span> isStarred={recipe.isStarred}
{recipe.starCount} starCount={recipe.starCount}
</button> {...{ username, slug }}
/>
) : (
<RecipeStarInfo starCount={recipe.starCount} />
)}
</div> </div>
<div className={classes.infoRow}> <div className={classes.infoRow}>
<UserIconAndName username={recipe.owner.username} /> <UserIconAndName username={recipe.owner.username} />

View File

@ -19,6 +19,7 @@
.info-row { .info-row {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center;
} }
.recipe-title { .recipe-title {
@ -29,12 +30,39 @@
width: 100%; width: 100%;
} }
.star-button { .star-container {
display: flex; display: flex;
column-gap: 5px; column-gap: 5px;
align-items: center; align-items: center;
height: 30px;
}
button.star-container {
cursor: pointer;
background-color: var(--off-white-1);
border: 1px solid var(--off-white-3);
border-radius: 5px;
}
button.star-container:hover {
background-color: var(--off-white-2);
} }
.star { .star {
color: var(--primary-yellow); color: var(--primary-yellow);
} }
.starred {
font-family: 'Inter', sans-serif;
font-size: 16px;
}
button .star-count {
font-family: 'Inter', sans-serif;
font-size: 16px;
background-color: var(--off-white-3);
min-width: 20px;
min-height: 16px;
border-radius: 50%;
text-align: center;
}